给定一个字符串
S
,找出字符a
出现的最后一个位置,没找到就输出-1
for一遍
#include
using namespace std;
#define endl '\n'
#define inf 0x3f3f3f3f
#define mod7 1000000007
#define mod9 998244353
#define m_p(a,b) make_pair(a, b)
#define mem(a,b) memset((a),(b),sizeof(a))
#define io ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
typedef long long ll;
typedef pair <int,int> pii;
#define MAX 300000 + 50
int n, m, k, x;
int tr[MAX];
void work(){
string s;
cin >> s;
for(int i = (int)s.size() - 1; i >= 0; --i){
if(s[i] == 'a'){
cout << i + 1 << endl;
return;
}
}
cout << -1 << endl;
}
int main(){
io;
work();
return 0;
}
n个点,m条边,对于每个点
i
,输出与i
相邻的点的个数以及所有与他相邻的点
vector
建图
#include
using namespace std;
#define endl '\n'
#define inf 0x3f3f3f3f
#define mod7 1000000007
#define mod9 998244353
#define m_p(a,b) make_pair(a, b)
#define mem(a,b) memset((a),(b),sizeof(a))
#define io ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
typedef long long ll;
typedef pair <int,int> pii;
#define MAX 300000 + 50
int n, m, k, x;
vector<int>v[MAX];
void work(){
cin >> n >> m;
for(int i = 1; i <= m; ++i){
int x, y;
cin >> x >> y;
v[x].push_back(y);
v[y].push_back(x);
}
for(int i = 1; i <= n; ++i){
cout << v[i].size();
sort(v[i].begin(), v[i].end());
for(auto x : v[i])cout << " " << x;
cout << endl;
}
}
int main(){
io;
work();
return 0;
}
给你一个长度为n的全排列,你需要输出他的上一个全排列
直接prev_permutation
#include
using namespace std;
#define endl '\n'
#define inf 0x3f3f3f3f
#define mod7 1000000007
#define mod9 998244353
#define m_p(a,b) make_pair(a, b)
#define mem(a,b) memset((a),(b),sizeof(a))
#define io ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
typedef long long ll;
typedef pair <int,int> pii;
#define MAX 300000 + 50
int n, m, k, x;
int tr[MAX];
void work(){
cin >> n;
for(int i = 1; i <= n; ++i)cin >> tr[i];
prev_permutation(tr+1, tr+1+n);
for(int i = 1; i <= n; ++i)cout << tr[i] << ' ';
cout << endl;
}
int main(){
io;
work();
return 0;
}
给你一个数组,你有两种操作:
- 选择一个是2的倍数的数字,让它除以2
- 选择一个是3的倍数的数字,让它除以3
问最少能通过多少次操作使得所有数字相等
显然最后的数字是
g=gcd(a1, a2, ... , an)
判断
a[i]
能不能变成g
的条件是:
a[i]%g==0
- 看
a[i]/g
能不能通过除2
除3
变成1
答案就是对每个
a[i]/g
变成1的操作次数求和
#include
using namespace std;
#define endl '\n'
#define inf 0x3f3f3f3f
#define mod7 1000000007
#define mod9 998244353
#define m_p(a,b) make_pair(a, b)
#define mem(a,b) memset((a),(b),sizeof(a))
#define io ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
typedef long long ll;
typedef pair <int,int> pii;
#define MAX 300000 + 50
int n, m, k, x;
ll tr[MAX];
ll gcd(ll a, ll b){
if(b) return gcd(b, a % b);
else return a;
}
ll fuck(ll x){
int ans = 0;
while(x % 2 == 0){
x /= 2;
++ans;
}
while(x % 3 == 0){
x /= 3;
++ans;
}
if(x == 1)return ans;
else return -1;
}
void work(){
cin >> n;
ll g = 0;
for(int i = 1; i <= n; ++i){
cin >> tr[i];
g = gcd(g, tr[i]);
}
ll ans = 0;
for(int i = 1; i <= n; ++i){
ll p = fuck(tr[i] / g);
if(p == -1){
cout << -1 << endl;
return;
}
ans += p;
}
cout << ans << endl;
}
int main(){
io;
work();
return 0;
}
给你一个
n*m
的字符矩阵,.
可以走,#
不可以走,S
是起点,问能不能找到一条回路,满足起点和终点都是S
点,且中间不会经过重复的点
可以发现
S
最多只有四个方向可以到达,所以如果能从一个点出,从另一个点进,则就可以满足要求,所以我们只需要跑出四个方向的点是否存在联通即可,我们可以用dfs暴力跑出整个图每个点的联通块,然后进行判断
#include
using namespace std;
#define endl '\n'
#define inf 0x3f3f3f3f
#define mod7 1000000007
#define mod9 998244353
#define m_p(a,b) make_pair(a, b)
#define mem(a,b) memset((a),(b),sizeof(a))
#define io ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
typedef long long ll;
typedef pair <int,int> pii;
#define MAX 1000000 + 50
int n, m, k, x;
int sx, sy;
string tr[MAX];
map<pii, int>mp;
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
bool judge(int x, int y){
if(x < 0 || x >= n || y < 0 || y >= m)return false;
else if(mp.count(m_p(x, y)))return false;
else if(tr[x][y] == '#')return false;
return true;
}
bool cao(int x, int y){
if(x < 0 || x >= n || y < 0 || y >= m)return false;
else if(tr[x][y] == '#')return false;
return true;
}
int col;
void dfs(int x, int y){
mp[m_p(x, y)] = col;
for(int i = 0; i < 4; ++i){
int xx = x + dx[i];
int yy = y + dy[i];
if(!judge(xx, yy))continue;
dfs(xx, yy);
}
}
void work(){
cin >> n >> m;
for(int i = 0; i < n; ++i){
cin >> tr[i];
}
for(int i = 0; i < n; ++i){
for(int j = 0; j < m; ++j){
if(tr[i][j] == 'S'){
tr[i][j] = '#';
sx = i;sy = j;
}
}
}
for(int i = 0; i < n; ++i){
for(int j = 0; j < m; ++j){
if(!mp.count(m_p(i, j)) && tr[i][j] != '#'){
++col;
dfs(i, j);
}
}
}
vector<int>a;
for(int i = 0; i < 4; ++i){
int xx = sx + dx[i];
int yy = sy + dy[i];
if(cao(xx, yy))a.push_back(mp[m_p(xx, yy)]);
}
for(int i = 0; i < a.size(); ++i){
for(int j = i + 1; j < a.size(); ++j){
if(a[i] == a[j]){
cout << "Yes\n";
return;
}
}
}
cout << "No\n";
}
int main(){
io;
work();
return 0;
}
n
个卡片,每个卡片的值为a[i]
对于前
K
个卡片,我们连续取两次卡片,每次取完都会放回去,计两张卡片的最大值为此次的ans
,求ans
的期望是多少
K
是从1
到n
的
我们要知道从
K
张卡片中抽出的所有情况的数量是K*K
,这就是期望的分母,分子应该是每种情况的答案的求和对于
K=i
的答案其实可以从K=i-1
推过来,因为只多了a[K]
这一个卡片,也就是只多了2*K-1
种抽法,而这2*K-1
种抽法贡献的答案可以分成两部分来计算,第一部分是x<=a[K]
的数,假设x<=a[K]
的x
的数量是num
,这些数字对分子的贡献是数量2*num+1
乘以a[K]
,第二部分是x>a[K]
的数,这些数字的对答案的贡献是这些数字的和(即前k-1个数字中出现的严格大于a[k]
的所有的数字的和)我们可以用两个树状数组来维护分子,对于每个答案,我们只需要再乘以
i*i
的逆元即可得到期望
#include
using namespace std;
#define endl '\n'
#define inf 0x3f3f3f3f
#define mod7 1000000007
#define mod9 998244353
#define m_p(a,b) make_pair(a, b)
#define mem(a,b) memset((a),(b),sizeof(a))
#define io ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
typedef long long ll;
typedef pair <int,int> pii;
#define lowbit(x) (x&(-x))
#define int long long
#define MAX 500000 + 50
int n, m, k, x;
int ar[MAX];
int rk[MAX];
void update(int i, int c){
while (i <= 400050) {
(rk[i] += c)%=mod9;
i += lowbit(i);
}
}
int getnum(int i){//1到i的和
int ans = 0;
while (i > 0) {
(ans += rk[i])%=mod9;
i -= lowbit(i);
}
return ans;
}
int sum[MAX];
inline void update2(int i, int c){
while (i <= 400050) {
(sum[i] += c)%=mod9;
i += lowbit(i);
}
}
inline int getnum2(int i){//1到i的和
int ans = 0;
while (i > 0) {
(ans += sum[i])%=mod9;
i -= lowbit(i);
}
return ans;
}
ll q_pow(ll a, ll b, ll MOD){
a%=MOD;
ll ans = 1;
while(b > 0){
if(b & 1)ans = ans * a % MOD;
a = a * a % MOD;
b >>= 1;
}
return ans;
}
inline ll getniyuan(ll a, ll p){
return q_pow(a, p - 2, p);
}
void work(){
cin >> n;
for(int i = 1; i <= n; ++i){
cin >> ar[i];
}
ll ans = 0;
for(int i = 1; i <= n; ++i){
int num = getnum(ar[i]);
update(ar[i], 1ll);
(ans = ans + ((2ll * num + 1) * ar[i])%mod9)%=mod9;
int cnt = ((getnum2(400000) - getnum2(ar[i])) + mod9) % mod9;
update2(ar[i], ar[i]);
(ans += 2ll*cnt)%=mod9;
int cao = (getniyuan((i*i)%mod9, mod9))%mod9;
cout << (ans * cao) % mod9 << endl;
}
}
signed main(){
io;
work();
return 0;
}