Http://codeforces.com/problemset/problem/232/D
Give you a sequence of length n, a set of two values L1,s, L2, satisfies:
1.[l1,l1+s?? 1] and [L2,l2+s?? 1] Do not intersect, all within [1,n].
2. For any 0<k<s, there is bk=a[l1+k]+a[l2+k], requiring all BK to be equal.
There is a Q group asking, for a given L1 and S, how many L2 meet the requirements.
It doesn't look like a string problem, but it can be transformed and embarrassing.
The conditions can be seen as such:
For 0<i<s,a[l1+i]+a[l2+i]=a[l1+i-1]+a[l2+i-1].
Move the item, get A[l1+i]-a[l1+i-1]=a[l2+i-1]-a[l2+i].
That is not to be seen as the difference array of the array and the difference in the group of each item in the inverse number of the resulting array of the length of the common substring of s? (There are, of course, the conditions 1 limit)
For each query, we find the rank of the suffix of the L1 starting point, i.e., RANK[L1], up and down to the Up,low ≥s interval, and then the equivalent of the number of suffixes in this interval that meet [sa[i],sa[i]+s-1] does not intersect [l1,l1+s-1]. Queries can be made with a durable line tree.
#include <bits/stdc++.h>using namespacestd;Const intmaxn=100015; Vector<int>W;intn,q,len,s[maxn],p[maxn<<1];structtsegment{Static Const intmaxn=::maxn<<1, maxk= -; intTot,l,r; structtnode{tnode*c[2];intsiz; }*root[maxn],t[maxn*MAXK]; voidClearintLintR) {L=l; r=r;tot=0; root[0]=t;root[0]->siz=0; root[0]->c[0]=root[0]->c[1]=root[0]; } tnode*newnode (Tnode *x) {Tnode*cur=t+ (+ +)tot); *cur=*x;returncur; } voidModify (Tnode *ever,tnode *&now,intLintRintx) { Now=newnode (Ever);++now->siz; intMid= (l+r) >>1;if(L==R)return; if(x<=mid) Modify (ever->c[0],now->c[0],l,mid,x); ElseModify (ever->c[1],now->c[1],mid+1, r,x); } intQuery (Tnode *ever,tnode *now,intLintRintAintb) { if(l==a&&r==b)returnNow->siz-ever->siz; if(A>B)return 0;intMid= (l+r) >>1; if(B<=mid)returnQuery (ever->c[0],now->c[0],l,mid,a,b); Else if(a>=mid+1)returnQuery (ever->c[1],now->c[1],mid+1, r,a,b); Else returnQuery (ever->c[0],now->c[0],l,mid,a,mid) +query (ever->c[1],now->c[1],mid+1, r,mid+1, B); } voidModifyintEver,intNowintx) {Modify (root[ever],root[now],l,r,x);} intQueryintEver,intNowintAintb) {returnquery (ROOT[EVER],ROOT[NOW],L,R,A,B);}} Segment;structtsuffix_array{Static Const intmaxn=::maxn<<1, maxk= -; intSUM[MAXN],SA[MAXN],RANK[MAXN],TSA[MAXN],TRANK[MAXN]; BOOLcmpintIintJintl) { if(i+l>len| | J+l>len)return 0; returnrank[i]==rank[j]&&rank[i+l]==rank[j+L]; } voidSuffix_sort (ints[]) { intm=len,p,i,j; for(i=0; i<=m;++i) sum[i]=0; for(i=1; i<=len;++i) ++sum[rank[i]=S[i]]; for(i=1; i<=m;++i) sum[i]+=sum[i-1]; for(i=len;i>=1;-I.) sa[sum[rank[i]]--]=i; for(j=1, p=0;p <len;j<<=1, m=p) { for(p=0, i=len-j+1; i<=len;++i) tsa[++p]=i; for(i=1; i<=len;++i)if(SA[I]>J) tsa[++p]=sa[i]-J; for(i=0; i<=m;++i) sum[i]=0; for(i=1; i<=len;++i) + +Sum[rank[tsa[i]]; for(i=1; i<=m;++i) sum[i]+=sum[i-1]; for(i=len;i>=1;-I.) sa[sum[rank[tsa[i]]]--]=Tsa[i]; for(p=trank[sa[1]]=1, i=2; i<=len;++i) trank[sa[i]]=cmp (sa[i],sa[i-1],J)? p:++p; memcpy (Rank,trank,sizeof(int) * (len+1)); } } intHEIGHT[MAXN]; voidGet_height (ints[]) { for(intH=0, i=1; i<=len;++i) { if(rank[i]==1)Continue; for(H?--H:0; s[i+h]==s[sa[rank[i]-1]+h];++h); Height[rank[i]]=h; } } intFMN[MAXK][MAXN]; voidprepare () { for(intI=1; i<=len;++i) fmn[0][i]=Height[i]; for(intk=1; k<maxk;++k) for(intI=1<<k;i<=len;++i) fmn[k][i]=min (fmn[k-1][i],fmn[k-1][i-(1<< (K-1))]); Segment.clear (1, Len); for(intI=1; i<=len;++i) segment.modify (i-1, I,sa[i]); } intLcpintLintR) { if(++l>r)returnlen-sa[r]+1; intK=LOG2 (r-l+1); returnMin (fmn[k][r],fmn[k][l+ (1<<K)-1]); } intCALC_UP (intPosintLim) { intL=1, r=Pos,res; while(l<=R) { intMid= (l+r) >>1; LCP (Mid,pos)>=lim?r= (Res=mid)-1: l=mid+1; } returnRes; } intCalc_low (intPosintLim) { intL=pos,r=Len,res; while(l<=R) { intMid= (l+r) >>1; LCP (Pos,mid)>=lim?l= (Res=mid) +1: r=mid-1; } returnRes; } intQueryintLintR) { intlength=r-l; intUp=calc_up (rank[l],length), low=Calc_low (rank[l],length); L+=n;r+=N; returnSegment.query (up-1, low,n+1, l-length-1) +segment.query (up-1, low,r+1, Len); }}sa;voidinit () {scanf ("%d", &n); Len= (n<<1)-1;p [n]=2e9+1; for(intI=1; i<=n;++i) scanf ("%d",&S[i]); for(intI=2; i<=n;++i) {p[i-1]=s[i]-s[i-1];p [n+i-1]=s[i-1]-s[i];} for(intI=1; i<=len;++i) w.push_back (P[i]); Sort (W.begin (), W.end ()), W.erase (Unique (W.begin (), W.end ()), W.end ()); for(intI=1; i<=len;++i) P[i]=lower_bound (W.begin (), W.end (), P[i])-w.begin () +1;}voidWork () {sa.suffix_sort (P); Sa.get_height (P); Sa.prepare (); scanf ("%d",&q); for(intL,r,i=1; i<=q;++i) {scanf ("%d%d",&l,&R); if(l==r) printf ("%d\n", N-1); Elseprintf"%d\n", Sa.query (l,r)); }}intMain () {init (); Work (); return 0;}My Code
codeforces232d. Fence