http://www.lydsy.com/JudgeOnline/problem.php?id=2534
Given the string s, the number of substrings in the form of ABA, where the length of B is L.
Consider the two starting position x, Y (x<y) of a, which should meet the following two conditions:
1.y>x+l
2.LCP (x, y) ≥y-x-l
We press the height from the large to the small enumeration, so that LCP becomes the current height, the two sets of statistical answers and merge. The statistical answer is to enumerate the points within the smaller collection of size as x or Y. Can be maintained with a balance tree or a chair tree.
#include <bits/stdc++.h>using namespacestd;Const intmaxn=50015; typedefLong LongInt64;typedef pair<int,int>PII;intn,l,cnt,q[maxn];int64 ans;CharS[MAXN];structtsplay{inttot; Static Const intMaxnode=1000015; structtnode{tnode*f,*c[2];intN,siz,val; voidUpdate () {siz=c[0]->siz+c[1]->siz+1;} voidLink (tnode *NEWF,intnewn) {N=NEWN;F=NEWF;if(n!=2) f->c[n]= This;} }t[maxnode],*root[maxn],*NULL; voidClear () {tot=0;NULL=t;NULL->c[0]=NULL->c[1]=NULL;NULL->siz=0; for(intI=1; i<=n;++i) root[i]=NULL; } tnode*newnode (intv) {Tnode*cur=t+ (+ +)tot); Cur->f=cur->c[0]=cur->c[1]=NULL; Cur->n=2; cur->val=v;cur->siz=1; returncur; } voidRotate (Tnode *x) {Tnode*y=x->f,*z=y->f;intNx=x->n,ny=y->N; X->link (Z,ny); X->c[!nx]->link (Y,NX); Y->link (x,!NX); Y-update (); } voidSplay (intP,tnode *x) { while(x->n!=2) {x->n==x->f->n?rotate (x->f): Rotate (x); if(x->n!=2) rotate (x); } Root[p]=x;x->update (); } voidInsertintPintval) {Tnode*x=Root[p]; if(x==NULL) {Root[p]=newnode (val);return;} while(1){ if(val<x->val) { if(x->c[0]==NULL) {x->c[0]=newnode (val); x->c[0]->link (x,0); Splay (p,x->c[0]);return;} Elsex=x->c[0]; } Else{ if(x->c[1]==NULL) {x->c[1]=newnode (val); x->c[1]->link (x,1); Splay (p,x->c[1]);return;} Elsex=x->c[1]; } } } intGreaterintPintv) {Tnode*res=NULL, *x=Root[p]; while(x!=NULL){ if(X->VAL>V) {res=x;x=x->c[0];} Elsex=x->c[1]; } if(res==NULL)return 0; Else{splay (p,res);returnres->c[1]->siz+1;} } intLessintPintv) {Tnode*res=NULL, *x=Root[p]; while(x!=NULL){ if(X->VAL<V) {res=x;x=x->c[1];} Elsex=x->c[0]; } if(res==NULL)return 0; Else{splay (p,res);returnres->c[0]->siz+1;} } voidTravel (Tnode *x) { if(x!=NULL) q[++cnt]=x->val;Else return; Travel (x->c[0]); Travel (x->c[1]); } intSizeintP) {returnRoot[p]->Siz;} voidTravelintx) {cnt=0; travel (root[x]);} voidMergeintT1,intT2) {Travel (T2); for(intI=1; i<=cnt;++i) insert (t1,q[i]); }}splay;structtsuffix_array{intSUM[MAXN],SA[MAXN],RANK[MAXN],TSA[MAXN],TRANK[MAXN]; BOOLcmpintIintJintl) { if(i+l>n| | J+l>n)return 0; returnrank[i]==rank[j]&&rank[i+l]==rank[j+L]; } voidSuffix_sort () {intm=255, P,i,j; for(i=0; i<=m;++i) sum[i]=0; for(i=1; i<=n;++i) ++sum[rank[i]=S[i]]; for(i=1; i<=m;++i) sum[i]+=sum[i-1]; for(i=n;i>=1;-I.) sa[sum[rank[i]]--]=i; for(p=0, j=1;p <n;j<<=1, m=p) { for(p=0, i=n-j+1; i<=n;++i) tsa[++p]=i; for(i=1; i<=n;++i)if(SA[I]>J) tsa[++p]=sa[i]-J; for(i=0; i<=m;++i) sum[i]=0; for(i=1; i<=n;++i) + +Sum[rank[tsa[i]]; for(i=1; i<=m;++i) sum[i]+=sum[i-1]; for(i=n;i>=1;-I.) sa[sum[rank[tsa[i]]]--]=Tsa[i]; for(p=trank[sa[1]]=1, i=2; i<=n;++i) trank[sa[i]]=cmp (sa[i],sa[i-1],J)? p:++p; memcpy (Rank,trank,sizeof(int) * (n+1)); } } intHEIGHT[MAXN]; voidget_height () { for(intH=0, i=1; i<=n;++i) { if(rank[i]==1)Continue; for(H?--H:0; s[i+h]==s[sa[rank[i]-1]+h];++h); Height[rank[i]]=h; } } intFA[MAXN]; PII T[MAXN]; intFindintx) {returnx==fa[x]?x:fa[x]=find (Fa[x]);} voidGet_ans () {splay.clear (); for(intI=1; i<=n;++i) {Splay.insert (i,sa[i]); fa[i]=i;} for(intI=2; i<=n;++i) t[i-1]=Make_pair (height[i],i); Sort (T+1,t+n,greater<pii>()); for(intI=1; i<=n-1;++i) { intcur_height=t[i].first,cur_rank=T[i].second; if(!cur_height) Break; intX=find (Cur_rank), Y=find (cur_rank-1); if(Splay.size (x) >splay.size (y)) swap (x, y); Splay.travel (x); for(intj=1; j<=cnt;++j) { intA=splay.greater (y,q[j]+l); intB=splay.less (y,cur_height+l+q[j]+1); Ans+ = (a+b-splay.size (y)); intC=splay.less (y,q[j]-l); intD=splay.greater (y,q[j]-cur_height-l-1); Ans+ = (c+d-splay.size (y)); } splay.merge (y,x); Fa[x]=y; }}}sa;voidinit () {scanf ("%d%s", &l,s+1); N=strlen (s+1); Sa.suffix_sort (); Sa.get_height ();}voidWork () {Sa.get_ans (); printf ("%lld\n", ans);}intMain () {init (); Work (); return 0;}
My Code
Bzoj2534:uva10829l-gap string