后缀数组的简单题吧。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int maxn=100000+10; 6 char s[maxn]; 7 int sa[maxn],t[maxn],t2[maxn],c[maxn]; 8 int rank[maxn],height[maxn]; 9 int d[maxn][50]; 10 void build_sa(int n,int m) 11 { 12 int i,*x=t,*y=t2; 13 for(i=0;i<m;i++) c[i]=0; 14 for(i=0;i<n;i++) c[x[i]=s[i]]++; 15 for(i=1;i<m;i++) c[i]+=c[i-1]; 16 for(i=n-1;i>=0;i--) sa[--c[x[i]]]=i; 17 18 for(int k=1;k<=n;k<<=1) 19 { 20 int p=0; 21 for(int j=n-k;j<n;j++) y[p++]=j; 22 for(i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k; 23 24 for(i=0;i<m;i++) c[i]=0; 25 for(i=0;i<n;i++) c[x[y[i]]]++; 26 for(i=1;i<m;i++) c[i]+=c[i-1]; 27 for(i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i]; 28 29 swap(x,y); 30 x[sa[0]]=0; 31 p=1; 32 for(i=1;i<n;i++) 33 x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++; 34 if(p>=n) break; 35 m=p; 36 } 37 } 38 void getHeight(int n) 39 { 40 int i,k=0; 41 for(i=1;i<=n;i++) rank[sa[i]]=i; 42 for(i=0;i<n;i++) 43 { 44 if(k) k--; 45 int j=sa[rank[i]-1]; 46 while(s[i+k]==s[j+k]) k++; 47 height[rank[i]]=k; 48 } 49 } 50 int rmq(int a,int b) 51 { 52 a=rank[a],b=rank[b]; 53 if(a>b) swap(a,b); 54 a++; 55 int k=0; 56 while((1<<(k+1))<=b-a+1)k++; 57 return min(d[a][k],d[b-(1<<k)+1][k]); 58 } 59 int main() 60 { 61 while(scanf("%s",s)!=EOF) 62 { 63 int n=strlen(s); 64 build_sa(n+1,128); 65 getHeight(n); 66 for(int i=1;i<=n;i++) d[i][0]=height[i]; 67 for(int j=1;(1<<j)<=n;j++) 68 for(int i=1;i+(1<<j)-1<=n;i++) 69 d[i][j]=min(d[i][j-1],d[i+(1<<(j-1))][j-1]); 70 int m,a,b,x,y; 71 scanf("%d",&m); 72 long long orgin=0,compress=0; 73 scanf("%d%d",&x,&y); 74 orgin+=(y-x+1); 75 compress+=(y-x+3); 76 m--; 77 while(m--) 78 { 79 scanf("%d%d",&a,&b); 80 orgin+=(b-a+1); 81 int tmp; 82 if(a!=x) 83 tmp=rmq(a,x); 84 else 85 tmp=min(b-a,y-x); 86 tmp=min(min(tmp,y-x),b-a); 87 int tmp2=tmp,cnt=0; 88 while(tmp2){tmp2/=10;cnt++;} 89 if(!cnt) cnt++; 90 compress+=(b-a+1+cnt+1-tmp); 91 x=a;y=b; 92 } 93 printf("%I64d %I64d ",orgin,compress); 94 } 95 return 0; 96 }