#include<cstdlib>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<set>
#include<map>
#include<list>
#include<queue>
#include<vector>
#define LL long long
#define inf 0x7fffffff
#define exp 1e-9
#define N 100009
using namespace std;
int m,n,t;
char s[N];
int sa[N],t1[N],t2[N],c[N];
int rank1[N],height[N];
void build_sa(int m,int n)//注意n=字符串长度加1!!!!
{
int *x=t1,*y=t2;
for (int i=0; i<m; ++i ) c[i]=0;//按一个字符基数排序
for (int i=0; i<n; ++i ) c[x[i]=s[i]]++;//
for(int i=1; i<m; ++i) c[i]+=c[i-1];
for(int i=n-1; i>=0; i--) sa[--c[x[i]]]=i;
for(int k=1; k<=n; k<<=1)
{
//按第二关键字排序
int p=0;
for(int i=n-k; i<n; i++) y[p++]=i;
for (int i=0; i<n; ++i )
if(sa[i]>=k) y[p++]=sa[i]-k;
for (int i=0; i<m; ++i ) c[i]=0;
for (int i=0; i<n; ++i ) c[x[y[i]]]++;
for(int i=1; i<m; ++i) c[i]+=c[i-1];
for(int i=n-1; i>=0; i--) sa[--c[x[y[i]]]]=y[i];
swap(x,y);
x[sa[0]]=0;
p=1;
for(int 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++;
if(p>=n)break;
m=p;
}
}
void getheight(int n)
{
int k=0;
for (int i=0; i<n; ++i )
{
rank1[sa[i]]=i;
}
for (int i=0; i<n; ++i )
{
if(k)k--;
if(rank1[i]==0)//
{
// k=0;//k一定等于0,可省略
continue;
}
int j=sa[rank1[i]-1];
while(s[i+k]==s[j+k])k++;
height[rank1[i]]=k;
}
}
int f[N][30];
void init()
{
for(int i=0; i<=n; i++)
{
f[i][0]=height[i];
}
for(int j=1; (1<<j)<=n; j++)
for(int i=0; i+(1<<j)-1<=n; i++)//必须是<=n,WA
f[i][j]=(min(f[i][j-1],f[i+(1<<(j-1))][j-1]));
}
int lcp(int l,int r)
{
int k=0;
while(1<<(k+1)<=(r-l+1))k++;
return min(f[l][k],f[r-(1<<k)+1][k]);
}
int wei(int x)
{
int ans=0;
while(x)
{
ans++;
x/=10;
}
return max(ans,1);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ex.in","r",stdin);
#endif
while(scanf("%s",s)==1)
{
n=strlen(s);
build_sa(N-1,n+1);
getheight(n+1);
init();
LL ans1=0,ans2=0;
int f=1,last=0,p=0;
int q;
scanf("%d",&q);
while(q--)
{
int x,y,l;
scanf("%d%d",&x,&y);
l=y-x;
ans1+=l+1;
int tp;
if(x==last)tp=l;
else
{
if(rank1[x]<rank1[last])
tp=lcp(rank1[x]+1,rank1[last]);
else
tp=lcp(rank1[last]+1,rank1[x]);
}
tp=min(tp,p);
ans2+=min(l,tp);
int w=wei(min(l,tp));
ans2-=w+1;
last=x;
p=l;
}
printf("%I64d %I64d\n",ans1,ans1-ans2);
}
return 0;
}
HDU 4691(后缀数组+lcp)水题
最新推荐文章于 2019-10-17 13:20:36 发布