CF-943(已更B-E,G1)
1.CF-925(已更新:D-F)2.2024牛客寒假算法基础集训营33.CF-926(已更新:B-C)4.CF-927(已更新:B C E)5.CF-928(已更新:B C D E)6.2024牛客寒假算法集训营4 (已更新:B-E)7.CF EDU-162 (已更新:A-C+D的代码)8.At-abc3429.蒟蒻的补档题(长期更新)10.CF-929(已更新:B-E)11.CF-931(已更新:AB代码)12.PowerOj 2024-康复赛 (待更新)13.CF-932(已更新 A B)14.矩阵快速幂15.CF-933(已更新:B-D)16.数论分块17.CF-Edu-163(已更新:A B)18.CF-936(AB)19.AT-abc347(C-E)20.CF-938(C-E)
21.CF-943(已更B-E,G1)
22.CF-945(已更A,B)23.CF-956(A-D)24.CF-957(D-E)25.CF-959(C-E)26.Codeforces Round 967 (Div. 2)-D27.AtCoder Beginner Contest 396 (E-F)28.Codeforces Round 1008 (Div. 2) (C-D)CF- 943(已更 B-E,G1)
D赛时没调出来(╬▔皿▔)╯,还有几分钟的时候反而把E过了,本来应该是上大分的一场(⊙﹏⊙)
这假期要刷题,还要补文化课……后面有空的话更一下之前打的线下赛的题解
B
双指针……
void solve(){
int n,m;cin>>n>>m;
string a,b;cin>>a>>b;
int now=0,ans=0;
rep(i,0,n-1){
while(a[i]!=b[now]&&now<m) now++;
if(a[i]==b[now]){//找到的话快指针now移动,合法长度ans++
now++;
ans++;
}
if(now==m){//找不到就break
break;
}
}
cout<<ans<<endl;
C
用到了一点数学知识
分析
已知 a[i]%a[i-1]=x[i]
则有 (a[i]-x[i])|a[i-1]
|表示能整除
所以 a[i]=k*a[i-1]+x[i]
但同时必有x[i]<a[i-1],由此可以得到k的取值
代码
void solve(){
int n;cin>>n;
rep(i,2,n){
cin>>x[i];
}
a[1]=x[2]+1;//由样例可知
rep(i,2,n){
int k=1;
if(i==n){
a[i]=a[i-1]+x[i];
continue;
}
while(a[i]<=x[i+1]){
a[i]=k*a[i-1]+x[i];
k++;
}
}
rep(i,1,n){
cout<<a[i]<<" ";
}
cout<<endl;
rep(i,1,n+1){
x[i]=a[i]=0;
}
}
D
考察了循环结构、顺序结构……反正我赛时是因为这个写假了
分析
暴力枚举两人会在哪个点开始一直停留,设这个点是now,此前已移动了pre次,那么之后对答案的贡献就是
比如10 8 2 10 3 1 4 5 2 7 8 10 6 9 5 10 5 1 3 7 10 15 4 3 对于后手: 一开始now=10,pre=0,res=0,若在该点一直停留对答案的贡献为a[10]*8=24; 此后: now=9,pre=1,res=3————3+a[9]*7=31 now=6,pre=2,res=7————7+a[6]*6=49 ————14+a[7]*5=64 ————24*a[8]*4=84 now=10,break;
正解代码
void solve(){
int n,k,ps,pb;cin>>n>>k>>pb>>ps;
rep(i,1,n) cin>>p[i];
rep(i,1,n) cin>>a[i];
int aa=0,bb=0;
if(p[pb]==pb) aa=k*a[pb];
if(p[ps]==ps) bb=k*a[ps];
int now=pb,pre=0,res=0;
while(1){
if(pre<=k){
aa=max(aa,res+a[now]*(k-pre));
}
res+=a[now];
now=p[now];
if(now==pb) break;
pre++;
}
now=ps,pre=0,res=0;
while(1){
if(pre<=k){
bb=max(bb,res+a[now]*(k-pre));
}
res+=a[now];
now=p[now];
if(now==ps) break;
pre++;
}
if(aa>bb){
cout<<"Bodya";
}
else if(aa<bb){
cout<<"Sasha";
}
else{
cout<<"Draw";
}
cout<<endl;
贴一个赛时样例都过不了的假写法,虽然思路是一样的(╬▔皿▔)╯
int now=pb,pre=0,res=0;
//cout<<now<<" "<<p[now]<<endl;
while(p[now]!=pb){//实际上p[now]=pb就跳出了
//cout<<now<<" "<<p[now]<<" "<<res<<endl;
if(pre<=k){
aa=max(aa,res+a[now]*(k-pre));
}
//else break;
//cout<<aa<<" "<<" "<<pre<<" "<<now<<" "<<res<<endl;
res+=a[now];
now=p[now];
pre++;
}
now=ps,pre=0,res=0;
while(p[now]!=ps){
if(pre<=k){
bb=max(bb,res+a[now]*(k-pre));
}
//else break;
//cout<<bb<<" "<<" "<<pre<<" "<<now<<" "<<res<<endl;
res+=a[now];
now=p[now];
pre++;
}
cout<<aa<<" "<<bb<<endl;
E
万恶的构造题
void solve(){
int n;cin>>n;
if(n==2){
cout<<"1 1"<<endl<<"2 2"<<endl<<endl;
return;
}
rep(i,1,n-2){
cout<<"1 "<<i<<endl;
}
cout<<n-1<<" 1"<<endl;
cout<<n<<" "<<n<<endl<<endl;
}
G1
这题磨了好久,因为自己之前不会找LCP,check里写了个自以为正确的n方的做法……后来问人才知道有Z函数可以o1查询LCP
缝了大佬的Z函数板子,自己也只会用,原理都还不懂……
分析
此题可供二分的单调性在于:最长公共前缀越长,可分的段数越少,于是所求答案就是可分段数为l或r的LCP的最大值,这个最大值可以二分求得
代码
string s;
const int N=3e5+5;
int n,x;
int z[N];
bool ck(int mid){
int cnt=0;//可分的段数
rep(i,1,n){//z[i]表示原串从i开始的后缀的最长的lcp
if(z[i]>=mid){
i+=mid-1;
cnt++;
}
}
//cout<<mid<<" "<<cnt<<endl;
if(cnt>=x) return true;
else return false;
}
void solve(){
cin>>n>>x>>x;
cin>>s;
s=' '+s;
z[1]=n;
for(int i=2,l=1,r=1;i<=n;i++){
z[i]=(i<=r?min(z[i-l+1],r-i+1):0);
while(i+z[i]<=n&&s[i+z[i]]==s[1+z[i]]) z[i]++;
if(i+z[i]-1>r) r=i+z[i]-1,l=i;
//cout<<l<<" "<<r<<" "<<i<<z[i]<<endl;
}
int l=0,r=n/x+1,mid;//二分的
while(r-l>1){
mid=l+r>>1;
if(ck(mid)) l=mid;
else r=mid;
}
cout<<l<<endl;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】