#include<bits/stdc++.h>usingnamespace std;#defineintlonglong#definedoublelongdoubleusing i64 =longlong;typedef pair<int,int> PII;typedef pair<int,char> PIC;typedef pair<double,double> PDD;typedef pair<int, PII> PIII;typedef pair<int, pair<int,bool>> PIIB;constint N =1e5+10;constint maxn =1e6;constint MAXN =1e5+10;constint mod =1e9+7;constint mod1 =954169327;constint mod2 =906097321;constint INF =0x3f3f3f3f3f3f3f3f;voidsolve(){int n, k; cin >> n >> k;while(k --){n =(n +1)/2;if(n ==1|| n ==0)break;}cout << n <<'\n';}signedmain(){ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t =1;cin >> t;while(t--){solve();}return0;}
B - Median(图论 找前缀后缀)
如果 a a a 比 b b b 大,就连一条从 a a a 指向 b b b 的有向边,如果图中有环肯定不行,没有环就计算每个点前缀有多少个点,后缀有多少个点,前缀后缀都小于 n 2 \frac{n}{2} 2n 就可以了
#include<bits/stdc++.h>usingnamespace std;#defineintlonglong#definedoublelongdoubleusing i64 =longlong;typedef pair<int,int> PII;typedef pair<int,char> PIC;typedef pair<double,double> PDD;typedef pair<int, PII> PIII;typedef pair<int, pair<int,bool>> PIIB;constint N =1e5+10;constint maxn =1e6;constint MAXN =1e5+10;constint mod =1e9+7;constint mod1 =954169327;constint mod2 =906097321;constint INF =0x3f3f3f3f3f3f3f3f;voidsolve(){int n, m; cin >> n >> m;vector<vector<int>>g(n +1);bool flag =true;for(int i =1; i <= m; i ++){int a, b; cin >> a >> b;if(a == b) flag =false;g[a].push_back(b);}if(!flag){for(int i =1; i <= n; i ++) cout <<0;cout <<'\n';return;}vector<int>from(n +1),pre(n +1),suf(n +1);auto bfs =[&](int rt){queue<int> q;q.push(rt);from[rt]= rt;while(q.size()){auto t = q.front();q.pop();for(int i =0; i < g[t].size(); i ++){int j = g[t][i];if(j == rt)returnfalse;if(from[j]== rt)continue;q.push(j);from[j]= rt;pre[j]++, suf[rt]++;}}returntrue;};for(int i =1; i <= n; i ++){if(!bfs(i)){for(int j =1; j <= n; j ++) cout <<0;cout <<'\n';return;}}for(int i =1; i <= n; i ++){if(pre[i]<= n /2&& suf[i]<= n /2) cout <<1;else cout <<0;}cout <<'\n';}signedmain(){ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t =1;cin >> t;while(t--){solve();}return0;}
C - Tokens on the Segments(贪心 优先队列)
从小到大放到优先队列里,记录当前可以选的最小的 x x x,记作 p o s pos pos
每次取出队头,看能不能取到 p o s pos pos,不能就把区间更新为 [ p o s , r ] [pos,\ r] [pos,r](如果不能这样更新肯定就是直接丢掉了),再存到堆里,可以就累加答案,更新 p o s pos pos
#include<bits/stdc++.h>usingnamespace std;#defineintlonglong#definedoublelongdoubleusing i64 =longlong;typedef pair<int,int> PII;typedef pair<int,char> PIC;typedef pair<double,double> PDD;typedef pair<int, PII> PIII;typedef pair<int, pair<int,bool>> PIIB;constint N =1e5+10;constint maxn =1e6;constint MAXN =1e5+10;constint mod =1e9+7;constint mod1 =954169327;constint mod2 =906097321;constint INF =0x3f3f3f3f3f3f3f3f;voidsolve(){int n; cin >> n;priority_queue<PII, vector<PII>, greater<PII>> pq;for(int i =0; i < n; i ++){int l, r;cin >> l >> r;pq.push({l, r});}int pos =1;int ans =0;while(pq.size()){auto t = pq.top();pq.pop();int l = t.first, r = t.second;if(pos > l){l = pos;if(l > r)continue;pq.push({l, r});continue;}else{ans ++;pos = l +1;}}cout << ans <<'\n';}signedmain(){ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t =1;cin >> t;while(t--){solve();}return0;}
D - Stones in the Bucket(签到 思维)
能求出每一堆最后会剩下多少石子,一定是从多的里面拿,那看多了多少就行
#include<bits/stdc++.h>usingnamespace std;#defineintlonglong#definedoublelongdoubleusing i64 =longlong;typedef pair<int,int> PII;typedef pair<int,char> PIC;typedef pair<double,double> PDD;typedef pair<int, PII> PIII;typedef pair<int, pair<int,bool>> PIIB;constint N =1e5+10;constint maxn =1e6;constint MAXN =1e5+10;constint mod =1e9+7;constint mod1 =954169327;constint mod2 =906097321;constint INF =0x3f3f3f3f3f3f3f3f;voidsolve(){int n; cin >> n;vector<int>a(n +1);int sum =0;for(int i =1; i <= n; i ++){cin >> a[i];sum += a[i];}int cnt = sum / n;int more =0;for(int i =1; i <= n; i ++){if(a[i]> cnt) more += a[i]- cnt;}cout << more <<'\n';}signedmain(){ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t =1;cin >> t;while(t--){solve();}return0;}
E - BaoBao Loves Reading(树状数组)
记录每本书上一次看的时间,如果从上一次看到这一次中间书的种类超过 k k k,就需要重新拿回来
区间种类数,用树状数组维护
最后后缀和计算
#include<bits/stdc++.h>usingnamespace std;#defineintlonglong#definedoublelongdoubleusing i64 =longlong;typedef pair<int,int> PII;typedef pair<int,char> PIC;typedef pair<double,double> PDD;typedef pair<int, PII> PIII;typedef pair<int, pair<int,bool>> PIIB;constint N =1e5+10;constint maxn =1e6;constint MAXN =100;constint mod =998244353;constint mod1 =954169327;constint mod2 =906097321;constint INF =0x3f3f3f3f3f3f3f3f;int n, tree[N];intlowbit(int x){return x &-x;}voidadd(int i,int x){while(i < N){tree[i]+= x;i +=lowbit(i);}}intprefix_sum(int i){int presum =0;while(i >0){presum += tree[i];i -=lowbit(i);}return presum;}intquery(int l,int r){returnprefix_sum(r)-prefix_sum(l -1);}voidsolve(){cin >> n;for(int i =0; i < N; i ++) tree[i]=0;vector<int>last(n +1);vector<int>ans(n +2);for(int i =1; i <= n; i ++){int x; cin >> x;if(last[x]==0) ans[n]++;else{int tmp =query(last[x]+1, i -1);ans[tmp]++;add(last[x],-1);}add(i,1);last[x]= i;}for(int i = n; i >=1; i --) ans[i]+= ans[i +1];for(int i =1; i <= n; i ++){cout << ans[i];if(i != n) cout <<' ';}cout <<'\n';}signedmain(){ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t =1;cin >> t;while(t--){solve();}return0;}
F - Game on a Graph(树的边数)
图连通至少需要 n − 1 n-1 n−1 条边,然后就没了,这题也太水了
#include<bits/stdc++.h>usingnamespace std;#defineintlonglong#definedoublelongdoubleusing i64 =longlong;typedef pair<int,int> PII;typedef pair<int,char> PIC;typedef pair<double,double> PDD;typedef pair<int, PII> PIII;typedef pair<int, pair<int,bool>> PIIB;constint N =1e5+10;constint maxn =1e6;constint MAXN =1e5+10;constint mod =1e9+7;constint mod1 =954169327;constint mod2 =906097321;constint INF =0x3f3f3f3f3f3f3f3f;voidsolve(){int k; cin >> k;string s; cin >> s;s =" "+ s;int n, m; cin >> n >> m;for(int i =1; i <= m; i ++){int x; cin >> x >> x;}int pos = m -(n -2);pos %= k;if(pos ==0) pos = k;if(s[pos]=='1') cout <<2<<'\n';else cout <<1<<'\n';}signedmain(){ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t =1;cin >> t;while(t--){solve();}return0;}
H - Wandering Robot(思维)
最大距离只会出现在第一次循环和最后一次循环
#include<bits/stdc++.h>usingnamespace std;#defineintlonglong#definedoublelongdoubleusing i64 =longlong;typedef pair<int,int> PII;typedef pair<int,char> PIC;typedef pair<double,double> PDD;typedef pair<int, PII> PIII;typedef pair<int, pair<int,bool>> PIIB;constint N =1e5+10;constint maxn =1e6;constint MAXN =1e5+10;constint mod =1e9+7;constint mod1 =954169327;constint mod2 =906097321;constint INF =0x3f3f3f3f3f3f3f3f;voidsolve(){int n, k; cin >> n >> k;string s;cin >> s;int x =0, y =0;vector<PII>maxx(4);// 左上 左下 右上 右下int ans =0;for(auto t : s){if(t =='U') y ++;elseif(t =='D') y --;elseif(t =='L') x --;else x ++;ans =max(ans,llabs(x)+llabs(y));}x = x *(k -1);y = y *(k -1);for(auto t : s){if(t =='U') y ++;elseif(t =='D') y --;elseif(t =='L') x --;else x ++;ans =max(ans,llabs(x)+llabs(y));}cout << ans <<'\n';}signedmain(){ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t =1;cin >> t;while(t--){solve();}return0;}
K - Happy Equation(数论)
打表发现, a a a 是奇数答案为 1 1 1 (不会证明)
a a a 是偶数的时候:
如果 x ≥ p x\geq p x≥p,那 a x a^x ax 一定有一个因数是 2 x 2^x 2x,也就一定有一个因数是 2 p 2^p 2p,所以 a x m o d 2 p = 0 a^x\mod 2^p=0 axmod2p=0,所以现在是要让 x a m o d 2 p = 0 x^a\mod 2^p=0 xamod2p=0,设 x x x 中有 k k k 个 2 2 2,那么 k a ≥ p ka\geq p ka≥p,所以 k ≥ ⌈ p a ⌉ = k ′ k\geq \lceil \frac{p}{a}\rceil=k' k≥⌈ap⌉=k′,也就是在 [ p , 2 p ] [p,\ 2^p] [p,2p] 找 2 k ′ 2^{k'} 2k′ 的倍数
否则,枚举计算
#include<bits/stdc++.h>usingnamespace std;#defineintlonglong#definedoublelongdoubleusing i64 =longlong;typedef pair<int,int> PII;typedef pair<int,char> PIC;typedef pair<double,double> PDD;typedef pair<int, PII> PIII;typedef pair<int, pair<int,bool>> PIIB;constint N =1e5+10;constint maxn =1e6;constint MAXN =100;constint mod =998244353;constint mod1 =954169327;constint mod2 =906097321;constint INF =0x3f3f3f3f3f3f3f3f;intpow(int a,int n,int p){int ans =1;while(n){if(n &1) ans = ans * a % p;a = a * a % p;n >>=1;}return ans;}voidsolve(){int a, p; cin >> a >> p;if(a &1) cout <<1<<'\n';else{int ans =0;for(int x =1; x < p; x ++){if(pow(a, x,(1<< p))==pow(x, a,(1<< p))) ans ++;}int k =(p + a -1)/ a;ans +=(1<<(p - k))-(p -1)/(1<< k);cout << ans <<'\n';}}signedmain(){ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t =1;cin >> t;while(t--){solve();}return0;}
d p [ i ] [ j ] dp[i][j] dp[i][j] 表示前 i i i 个操作后,还有 j j j 盏灯亮着
可以由 d p [ i ] [ j ] dp[i][j] dp[i][j],转移第 i + 1 i+1 i+1 个状态,如果在第 i + 1 i+1 i+1 个操作熄灭了 x x x 盏灯,也就是点亮了 m − x m-x m−x 盏灯
d p [ i + 1 ] [ j − x + ( m − x ) ] + = d p [ i ] [ j ] × C j x × C n − j m − x dp[i+1][j-x+(m-x)]+=dp[i][j]\times C_j^x\times C_{n-j}^{m-x} dp[i+1][j−x+(m−x)]+=dp[i][j]×Cjx×Cn−jm−x
#include<bits/stdc++.h>usingnamespace std;#defineintlonglong#definedoublelongdoubleusing i64 =longlong;typedef pair<int,int> PII;typedef pair<int,char> PIC;typedef pair<double,double> PDD;typedef pair<int, PII> PIII;typedef pair<int, pair<int,bool>> PIIB;constint N =1e5+10;constint maxn =1e6;constint MAXN =100;constint mod =998244353;constint mod1 =954169327;constint mod2 =906097321;constint INF =0x3f3f3f3f3f3f3f3f;int C[110][110];voidinit(){for(int i =0; i <= MAXN; i ++){C[i][0]=1;for(int j =1; j <= i; j ++)C[i][j]=(C[i -1][j -1]+ C[i -1][j])% mod;}}voidsolve(){int n, k, m; cin >> n >> k >> m;string s, t; cin >> s >> t;int cnt =0;for(int i =0; i < n; i ++){if(t[i]!='0'){t[i]='0';if(s[i]=='1') s[i]='0';else s[i]='1';}if(s[i]!= t[i]) cnt ++;}vector<vector<int>>dp(k +1,vector<int>(n +1));dp[0][cnt]=1;for(int i =0; i < k; i ++){for(int j =0; j <= n; j ++){for(int x =0; x <= j && x <= m; x ++){if(n - j < m - x)continue;dp[i +1][j - x +(m - x)]=(dp[i +1][j - x +(m - x)]+ dp[i][j]* C[j][x]% mod * C[n - j][m - x]% mod)% mod;}}}cout << dp[k][0]<<'\n';}signedmain(){ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);init();int t =1;cin >> t;while(t--){solve();}return0;}