#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;}