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