aaa 4 0 2 3 5
1 1 1 3 1 2 0 0
#include<algorithm> #include<iostream> #include<string.h> #include<stdio.h> using namespace std; const int INF=0x3f3f3f3f; const int maxn=100010; typedef long long ll; #define lson L,mid,ls #define rson mid+1,R,rs char txt[maxn]; int sa[maxn],T1[maxn],T2[maxn],ct[maxn],he[maxn],rk[maxn],n,m,le,ri; int rmq[25][maxn],lg[maxn],id[25][maxn],pos,len; ll num[maxn<<2]; void build(int L,int R,int rt) { if(L==R) { num[rt]=n-sa[L]-he[L]; return; } int ls=rt<<1,rs=ls|1,mid=(L+R)>>1; build(lson); build(rson); num[rt]=num[ls]+num[rs]; } void getsa(char *st) { int i,k,p,*x=T1,*y=T2; for(i=0; i<m; i++) ct[i]=0; for(i=0; i<n; i++) ct[x[i]=st[i]]++; for(i=1; i<m; i++) ct[i]+=ct[i-1]; for(i=n-1; i>=0; i--) sa[--ct[x[i]]]=i; for(k=1,p=1; p<n; k<<=1,m=p) { for(p=0,i=n-k; i<n; i++) y[p++]=i; for(i=0; i<n; i++) if(sa[i]>=k) y[p++]=sa[i]-k; for(i=0; i<m; i++) ct[i]=0; for(i=0; i<n; i++) ct[x[y[i]]]++; for(i=1; i<m; i++) ct[i]+=ct[i-1]; for(i=n-1; i>=0; i--) sa[--ct[x[y[i]]]]=y[i]; for(swap(x,y),p=1,x[sa[0]]=0,i=1; i<n; i++) x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++; } } void gethe(char *st) { int i,j,k=0; for(i=0;i<n;i++) rk[sa[i]]=i; for(i=0;i<n-1;i++) { if(k) k--; j=sa[rk[i]-1]; while(st[i+k]==st[j+k]) k++; he[rk[i]]=k; } } void rmq_init() { int i,j; for(i=0;i<n;i++) { rmq[0][i]=he[i]; id[0][i]=sa[i]; } for(i=1;i<=lg[n];i++) for(j=0;j+(1<<i)-1<n;j++) { rmq[i][j]=min(rmq[i-1][j],rmq[i-1][j+(1<<(i-1))]); id[i][j]=min(id[i-1][j],id[i-1][j+(1<<(i-1))]); } } int rmq_min(int l,int r) { if(l>r) return 0; int tmp=lg[r-l+1]; return min(rmq[tmp][l],rmq[tmp][r-(1<<tmp)+1]); } int rmq_id(int l,int r) { int tmp=lg[r-l+1]; return min(id[tmp][l],id[tmp][r-(1<<tmp)+1]); } void prermq() { int i; lg[0]=-1; for(i=1;i<maxn;i++) lg[i]=lg[i>>1]+1; } void qu(int L,int R,int rt,ll k) { if(k>num[rt]) { pos=-1; le=ri=0; return; } if(L==R) { pos=L; len=he[L]+k; return; } int ls=rt<<1,rs=ls|1,mid=(L+R)>>1; if(num[ls]>=k) qu(lson,k); else qu(rson,k-num[ls]); } int binl(int x) { int low=1,hi=x-1,mid,ans=x; while(low<=hi) { mid=(low+hi)>>1; if(rmq_min(mid+1,x)>=len) ans=mid,hi=mid-1; else low=mid+1; } return ans; } int binr(int x) { int low=x+1,hi=n,mid,ans=x; while(low<=hi) { mid=(low+hi)>>1; if(rmq_min(x+1,mid)>=len) ans=mid,low=mid+1; else hi=mid-1; } return ans; } inline ll ReadInt() { char ch = getchar(); if (ch==EOF) return -1; ll data = 0; while (ch < '0' || ch > '9') { ch = getchar(); if (ch==EOF) return -1; } do { data = data*10 + ch-'0'; ch = getchar(); } while (ch >= '0' && ch <= '9'); return data; } inline void putit(int x) { if (x/10>0) putit(x/10); putchar(x%10+'0'); } int main() { int q,lll,rrr; ll kth; prermq(); while(~scanf("%s",txt)) { m=150,n=strlen(txt); n++; getsa(txt); gethe(txt); rmq_init(); n--; build(1,n,1); scanf("%d",&q); le=ri=0; while(q--) { kth=ReadInt(); kth=(le^ri^kth)+1; qu(1,n,1,kth); if(pos==-1) putit(le),putchar(' '),putit(ri),putchar('\n'); else { lll=binl(pos); rrr=binr(pos); le=rmq_id(lll,rrr)+1; ri=le+len-1; putit(le),putchar(' '),putit(ri),putchar('\n'); } } } return 0; }
hdu 5008(2014 ACM/ICPC Asia Regional Xi'an Online ) Boring String Problem(后缀数组&二分)
原文地址:http://blog.csdn.net/bossup/article/details/39274213