hdu 4763 看毛片(单纯next数组的应用--纯正O(n))
因为需要负责队内的字符串题,开始刷,做到这道,开始想不出来,上网找题解,
然后就惊了,为什么你们这么暴力都可以过的啊,1e6啊,后来又想了下会做了
贴下代码
#include <iostream> #include <cstring> #include <cstdio> #include <map> #include <algorithm> #define mst(a,b) memset(a,b,sizeof(a)) #define lowbit(x) (x&(-x)) using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii; typedef pair<ll,ll> pll; const int mod=1e9+21; const int inf=0x3f3f3f3f; const ll INF=0x3f3f3f3f3f3f3f3f; const int maxn=1e6+50; char x[maxn]; int nx[maxn]; void init(int m){ int i=0,j=nx[0]=-1; while(i<m){ while(-1!=j and x[i]!=x[j])j=nx[j]; nx[++i]=++j; } } int mx[maxn]; int solve(){ cin>>x; int n=strlen(x); init(n); for(int i=1;i<=n;++i) mx[i]=0; for(int i=n-1;i;--i){ if(nx[i]>0){ mx[nx[i]]=max(mx[nx[i]],mx[i]); mx[nx[i]]=max(mx[nx[i]],min(n-i,i/2)); } } int ans=0; for(int i=nx[n];i>0;i=nx[i]) if(mx[i]>=i)ans=max(ans,i); return ans; } int main(){ #ifdef local freopen("in.txt","r",stdin); #endif ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int T;cin>>T; while(T--) cout<<solve()<<"\n"; return 0; }
假设E在字符串中的三次匹配为A B C,那么A必在B和C的fail链中
C是字符串的后缀
枚举B的结束位置为x,那么A在B的fail链中出现,那么B可接受的A的长度<= min( n-x,x/2)
然后一直往nx推,最后从n的fail链上找符合的,就是答案了