CF1968G2.Division+LCP-字符串、Z函数
link:https://codeforces.com/problemset/problem/1968/G2
给一个字符串
对于这样的划分问题,首先需要注意到的(显然的事实)是:
那么就可以想,暴力枚举
判断
难道会是什么神奇的后缀结构吗(并不会后缀xxx系列…),可恶,难道就到此为止了吗…
不可以,div3不会是这样的难度,让我们来想点稍微简单的东西,KMP麻烦就麻烦在要把整个串跑一遍,而我们知道枚举前缀
等一下!Z函数是求什么来着的?
总复杂度
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define endl '\n' #define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0) using namespace std; const int N=2e5+5; vector<int> exKMP(const string &s){ int n=s.length(); vector<int> z(n); for(int i=1,l=0,r=0;i<n;++i){ if(i<=r&&z[i-l]<r-i+1)z[i]=z[i-l]; else{ z[i]=max(0,r-i+1); while(i+z[i]<n&&s[z[i]]==s[i+z[i]])++z[i]; } if(i+z[i]-1>r)l=i,r=i+z[i]-1; } return z; } int n,l,r,tag[N]; int f[21][N],Log[N]; string s; int query(int l,int r){ int k=Log[r-l+1]; return max(f[k][l],f[k][r-(1<<k)+1]); } int main(){ fastio; Log[0]=-1; rep(i,1,N-5)Log[i]=Log[i>>1]+1; int tc;cin>>tc; while(tc--){ cin>>n>>l>>r>>s; auto z=exKMP(s); rep(i,0,n-1)f[0][i]=z[i]; rep(i,0,n)tag[i]=0; rep(j,1,20)for(int i=0;i+(1<<j)-1<n;i++) f[j][i]=max(f[j-1][i],f[j-1][i+(1<<(j-1))]); auto work=[&](int k){ int cnt=1; for(int i=0;i<n;){ int L=i+k,R=n-1,ret=-1; while(L<=R){ int mid=(L+R)>>1; if(query(i+k,mid)>=k){ ret=mid; R=mid-1; }else L=mid+1; } if(ret==-1)break; cnt++; i=ret; } tag[cnt]=max(tag[cnt],k); }; rep(i,1,n)work(i); tag[n+1]=0; for(int i=n;i>=1;i--)tag[i]=max(tag[i],tag[i+1]); rep(i,l,r)cout<<tag[i]<<' '; cout<<endl; } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】