HDU_4691 Front compression
来源:互联网 发布:刷qq会员靠谱吗 知乎 编辑:程序博客网 时间:2024/06/05 19:25
//题意就不啰嗦了,据说数据很水,暴力也可以A。。不过,觉得后缀数组才是正道。
//time:1234ms#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;const int N=100010;char s[N];int sa[N],t[N],t2[N],c[N],n;int rank[N],height[N];void build_sa(int m){ int i,*x=t,*y=t2,*tmp; for(i=0;i<m;++i) c[i]=0; for(i=0;i<n;++i) c[x[i]=s[i]]++; for(i=1;i<m;++i) c[i]+=c[i-1]; for(i=n-1;i>=0;--i) sa[--c[x[i]]]=i; for(int k=1,p;k<=n;k<<=1) { p=0; for(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) c[i]=0; for(i=0;i<n;++i) c[x[y[i]]]++; for(i=1;i<m;++i) c[i]+=c[i-1]; for(i=n-1;i>=0;--i) sa[--c[x[y[i]]]]=y[i]; tmp=x; x=y; y=tmp; p=1; x[sa[0]]=0; for(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 i,j,k=0; for(i=0;i<n;++i) rank[sa[i]]=i; for(i=0;i<n;++i) { k?--k:0; j=sa[rank[i]-1]; while(s[i+k]==s[j+k]) ++k; height[rank[i]]=k; }}int d[N][20];void initRMQ(){ for(int i=0;i<n;++i) d[i][0]=height[i]; for(int j=1;(1<<j)<=n;++j) for(int i=0;i+(1<<j)-1<n;++i) { d[i][j]=min(d[i][j-1],d[i+(1<<(j-1))][j-1]); }}int RMQ(int L,int R){ int k=0; while((1<<k+1)<=R-L+1) ++k; return min(d[L][k],d[R-(1<<k)+1][k]);}int LCP(int a,int b){ a=rank[a]; b=rank[b]; if(a>b) swap(a,b); return RMQ(a+1,b);}int A[N],B[N];int one(int a){ if(!a) return 1; int ret=0; while(a){ ++ret; a/=10; } return ret;}int main(){ //freopen("1006.in","r",stdin); //freopen("06.out","w",stdout); ios::sync_with_stdio(false); long long ans1,ans2; int k,tmp; //cout<<int('z')<<" "<<int('Z'); while(cin>>s) { memset(height,0,sizeof height); n=strlen(s); n++; build_sa(128); getHeight(); initRMQ(); cin>>k; ans1=0,ans2=0; for(int i=1;i<=k;++i) { cin>>A[i]>>B[i]; if(i==1) { ans1=B[i]-A[i]+1; ans2=ans1+2; continue; } if(A[i]!=A[i-1]) tmp=LCP(A[i],A[i-1]); else tmp=0x3f3f3f3f; tmp=min(tmp,B[i]-A[i]); tmp=min(tmp,B[i-1]-A[i-1]); ans1+=B[i]-A[i]+1; ans2+=B[i]-A[i]-tmp+2; ans2+=one(tmp); } cout<<ans1<<" "<<ans2<<endl; } //fclose(stdin); //fclose(stdout);}