Codeforces Round #770(Div. 2)
A-Reverse and Concatenate
规定操作能把字符串反转,现有两种操作:把变成;把变成。有次询问,每次你有一个长度为的字符串,你能进行次操作,问你能把原串变成多少种不同的串,输出答案。
思路
我们很容易能知道,进行一次操作就能得到一个回文串,而回文串进行的两种操作得到的答案相同,所以如果一开始就是回文串,答案就是,如果不是,如果为,则答案为,否则,答案为,就结束了。
代码
#include<bits/stdc++.h> using namespace std; typedef long long ll; char s[1000005]; int main() { int _; scanf("%d",&_); while(_--) { int n,t; scanf("%d%d",&n,&t); scanf("%s",s+1); bool ck=1; for(int i=1;i<=n>>1;i++)if(s[i]!=s[n-i+1]){ck=0;break;} if(ck)printf("1\n"); else { if(t==0)printf("1\n"); else printf("2\n"); } } return 0; }
B-Fortune Telling
有次询问,每次有一个,然后是个非负数,对于每个数有两种操作:把变成;把变成。问经过次操作后,还是能变成。
思路
蒟蒻不会,看了题解也只能勉强做出。首先我们要知道的是运算和对数值奇偶性的改变是一样的,而且和的奇偶性不同,而且和中必有一个能变成,因此问题就轻轻松松被解决了。
代码
#include<bits/stdc++.h> using namespace std; typedef long long ll; int main() { int _; scanf("%d",&_); while(_--) { int n,x; ll y; scanf("%d%d%lld",&n,&x,&y); int num=0; int a; for(int i=1;i<=n;i++) { scanf("%d",&a); if(a%2)num++; } if(x%2==y%2) { if(num%2)printf("Bob\n"); else printf("Alice\n"); } else { if(num%2)printf("Alice\n"); else printf("Bob\n"); } } return 0; }
C-OKEA
有次询问,每次询问有一个,输出的格式为“”加上行列到中的值(且每一项仅能输出一次)或“”。如果能够满足每一行中任意到的平均值为一个整数,则输出前者,否则,输出后者。
思路
显然我们可以知道为时可以直接按顺序输出,同时我们也可以知道在其余情况中,为奇数的情况一定为“”,偶数的情况一定为“”,且经过简单构造后就能直接啦。
代码
#include<bits/stdc++.h> using namespace std; typedef long long ll; int main() { int _; scanf("%d",&_); while(_--) { int n,k; scanf("%d%d",&n,&k); if(k==1) { printf("YES\n"); for(int i=1;i<=n;i++)printf("%d\n",i); } else if(k>=2) { if(n%2)printf("NO\n"); else { printf("YES\n"); for(int i=1;i<=n>>1;i++) { for(int j=k;j>=1;j--) { printf("%d ",i*2*k-2*j+1); } printf("\n"); for(int j=k;j>=1;j--) { printf("%d ",i*2*k-2*j+2); } printf("\n"); } } } } return 0 }
E-Fair Share
有组数据,每组有个元素。现要求你将每组数据分成个数相等的两份放到可重集合和中,问能否使得最后和相等,若可以,输出“”,并输出每个元素的去向,否则,输出“”。
思路
考虑二分图找欧拉回路,左部是个点,右部是个点,然后向左指代表到集合,向右指代表到集合中,然后就一直搜环就可以了。这里也附上大佬的题解。
代码
#include<bits/stdc++.h> using namespace std; vector<vector<int>>a(1e5+5),ans(1e5+5); map<int,int>mp,num; vector<vector<pair<int,int>>>v(4e5+5); vector<int>cnt(4e5+5); void dfs(int x,int dir) { int n=x; cnt[n]--; while(cnt[n]>-1&&ans[min(n,v[n][cnt[n]].first)][v[n][cnt[n]].second]!=-1)cnt[n]--; if(cnt[n]==-1)return; ans[min(n,v[n][cnt[n]].first)][v[n][cnt[n]].second]=dir; dfs(v[n][cnt[n]].first,1-dir); } int main() { int m; scanf("%d",&m); int tot=0; for(int i=1;i<=m;i++) { int n; scanf("%d",&n); a[i].resize(n+1); ans[i].resize(n+1,-1); for(int j=1;j<=n;j++) { scanf("%d",&a[i][j]); if(!mp[a[i][j]])mp[a[i][j]]=++tot; num[mp[a[i][j]]]++; } } for(int i=1;i<=tot;i++)if(num[i]%2) { printf("NO\n"); return 0; } int MAX=2e5; for(int i=1;i<=m;i++) { for(int j=1;j<a[i].size();j++) { v[i].push_back({mp[a[i][j]]+MAX,j}); v[mp[a[i][j]]+MAX].push_back({i,j}); cnt[i]++; cnt[mp[a[i][j]]+MAX]++; } } for(int i=1;i<=m;i++)dfs(i,0); printf("YES\n"); for(int i=1;i<=m;i++) { for(int j=1;j<ans[i].size();j++) { if(ans[i][j])printf("L"); else printf("R"); } printf("\n"); } return 0; }
F-Fibonacci Additions
规定一个斐波那契加法:从到,对分别加上,并且对进行取模,其中。现在有两个同样长度的数组和,有次操作,每次选择其中一个数组,对于到进行斐波那契加法。每次操作结束后,询问两数组是否相等。
思路
相比题,这题就出的非常巧妙。首先要使和相等,那么就可以构造一个,使得。而要加的又是斐波那契数列,那么可以想到差分。再构造一个数组,使得,那么就是在问数组中有没有不是的数字,而对和进行斐波那契加法就能转换为。这样问题就能被轻松解决了。
代码
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll a[300005],b[300005]; ll c[300005],d[300005]; ll F[300005]; int main() { int n,q; ll mod; scanf("%d%d%lld",&n,&q,&mod); F[1]=1;F[2]=1; for(int i=3;i<=n;i++)F[i]=(F[i-1]+F[i-2])%mod; for(int i=1;i<=n;i++)scanf("%lld",&a[i]); for(int i=1;i<=n;i++)scanf("%lld",&b[i]); for(int i=1;i<=n;i++)c[i]=((a[i]-b[i])%mod+mod)%mod; d[1]=c[1];d[2]=((c[2]-c[1])%mod+mod)%mod; for(int i=3;i<=n;i++) d[i]=((c[i]-c[i-1]-c[i-2])%mod+mod)%mod; int num=0; for(int i=1;i<=n;i++)num+=(d[i]!=0); while(q--) { char s; int l,r; scanf("\n%c%d%d",&s,&l,&r); if(s=='A') { num-=(d[l]!=0); (d[l]+=1)%=mod; num+=(d[l]!=0); if(r+1<=n) { num-=(d[r+1]!=0); ((d[r+1]-=F[r-l+2])%=mod+mod)%=mod; num+=(d[r+1]!=0); } if(r+2<=n) { num-=(d[r+2]!=0); ((d[r+2]-=F[r-l+1])%=mod+mod)%=mod; num+=(d[r+2]!=0); } } else { num-=(d[l]!=0); ((d[l]-=1)%=mod+mod)%=mod; num+=(d[l]!=0); if(r+1<=n) { num-=(d[r+1]!=0); (d[r+1]+=F[r-l+2])%=mod; num+=(d[r+1]!=0); } if(r+2<=n) { num-=(d[r+2]!=0); (d[r+2]+=F[r-l+1])%=mod; num+=(d[r+2]!=0); } } if(num)printf("NO\n"); else printf("YES\n"); } return 0; }
结论
对于将一个数组的一个区间同时加上另一个数组且加上的这个数组中的元素都能通过同样的规律从前面的元素中算得的这样一类题目都能通过差分来思考。
__EOF__

本文链接:https://www.cnblogs.com/Jerry-Black/p/15885679.html
关于博主:小蒟蒻一只( ̄^ ̄)ゞ
版权声明:转载请注明来源哟~ QAQ
声援博主:UP UP UP !!!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)