http://acm.hdu.edu.cn/showproblem.php?pid=4763
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
To get well prepared for the festival, the hosts want to know the maximum possible length of the theme section of each song. Can you help us?
#include<cstdio> #include<cstring> #include<algorithm> #define N 1000011 using namespace std; char s[N]; int len,nxt[N]; struct node { int l,r,maxn; }tr[N*4]; void getnxt() { int a=0; nxt[0]=len; while(a+1<len && s[a]==s[a+1]) a++; nxt[1]=a; int p,l,j; a=1; for(int k=2;k<len;k++) { p=a+nxt[a]-1; l=nxt[k-a]; if(k-1+l>=p) { j=p-k+1>0 ? p-k+1 : 0; while(k+j<len && s[k+j]==s[j]) j++; nxt[k]=j; a=k; } else nxt[k]=l; } } void build(int k,int l,int r) { tr[k].l=l; tr[k].r=r; if(l==r) { tr[k].maxn=nxt[l]; return; } int mid=l+r>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); tr[k].maxn=max(tr[k<<1].maxn,tr[k<<1|1].maxn); } int query(int k,int opl,int opr) { if(tr[k].l>=opl && tr[k].r<=opr) return tr[k].maxn; int mid=tr[k].l+tr[k].r>>1; int p=0,q=0; if(opl<=mid) p=query(k<<1,opl,opr); if(opr>mid) q=query(k<<1|1,opl,opr); return max(p,q); } int main() { int n,ans; scanf("%d",&n); while(n--) { scanf("%s",s); len=strlen(s); getnxt(); build(1,0,len); ans=0; for(int i=2;i<len;i++) { if(nxt[i]!=len-i) continue; if(i-nxt[i]<nxt[i]) continue; if(query(1,nxt[i],i-nxt[i])>=nxt[i]) { ans=nxt[i]; break; } } printf("%d\n",ans); } }