标签:des blog http io os ar java for strong
算是后缀数组的入门题吧。 思路无比简单,要是直接套模板的话应该很容易秒掉。
关于后缀数组看高中神犇的论文就可以学会了
话说这题暴力是可以过了,但是我们在做多校的时候就是用暴力过的,当时还不知道什么是后缀数组。。。
靠着概念纯手敲了几个小时,把建SA,求height,和RMQ的ST算法都复习了一遍,这个东西要是每次都手敲的话真的会死人,尤其是倍增算法基数排序怎么排怎么别扭。自己写的倍增算法又太长,大牛的倍增算法总感觉敲的不顺。
贴个代码做留念。。。
Time Limit: 5000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others)
Total Submission(s): 1344 Accepted Submission(s): 500
#include <iostream> #include <string.h> #include <stdio.h> #include <math.h> #include <algorithm> using namespace std; #define N 100100 char g[N]; int r[N]; int sa[N]; int scnt[N]; int wa[N],wb[N],wv[N]; int mrank[N]; int h[N],th[N]; int dp[N][22]; int save[N]; int cmp(int gg[],int a,int b,int k) { return gg[a]==gg[b] && gg[a+k]==gg[b+k]; } void getsa(int str[],int sa[],int n,int m) { int i,j,*x,*y,*t; x=wa; y=wb; memset(scnt,0,sizeof(scnt)); for(i=0;i<n;i++) scnt[ x[i]=str[i] ]++; for(i=1;i<m;i++) scnt[i]+=scnt[i-1]; for(i=0;i<n;i++) sa[ --scnt[ str[i] ] ]=i; for(int p=1,j=1;p<n;j*=2,m=p) { for(p=0,i=n-j;i<n;i++) y[p++]=i; for(i=0;i<n;i++) if( sa[i]>=j ) y[p++]=sa[i]-j; for(i=0;i<n;i++) wv[i]=x[ y[i] ]; memset(scnt,0,sizeof(scnt)); for(i=0;i<n;i++) scnt[ wv[i] ]++; for(i=1;i<m;i++) scnt[i]+=scnt[i-1]; for(i=n-1;i>=0;i--) sa[ --scnt[ wv[i] ] ] = y[i]; for(p=1,t=x,x=y,y=t,x[sa[0]]=0,i=1;i<n;i++) x[ sa[i] ] = cmp(y,sa[i],sa[i-1],j)?p-1:p++; } } void geth(int str[],int n) { h[n-1]=0; int p=0; for(int i=0;i<n-1;i++) { int tmp=mrank[i]; while( str[i+p] == str[ sa[tmp-1]+p ] ) p++; h[i]=p; p--; p=max(0,p); } } void buildst(int n) { for(int i=1;i<=n;i++) dp[i][0] = th[i]; for(int i=1;(1<<i)<=n;i++) { for(int j=1;j<=n;j++) { if( j+(1<<(i-1)) >n ) dp[j][i]=dp[j][i-1]; else dp[j][i]=min(dp[j][i-1],dp[j+(1<<(i-1))][i-1]); } } } int cal(int x,int y) { if(x>y) swap(x,y); x++; //然后就是求x到y的最小值 int k=0; while( (1<<k)<=(y-x+1) ) k++; k--; return min(dp[x][k],dp[y-(1<<k)+1][k]); } int main() { while(scanf("%s",g)!=EOF) { int len=strlen(g); for(int i=0;i<len;i++) r[i]=g[i]; r[len++]=0; getsa(r,sa,len,300); for(int i=0;i<len;i++) mrank[ sa[i] ]=i; //for(int i=0;i<len;i++) printf("%s\n",g+sa[i]); geth(r,len); for(int i=0;i<len-1;i++) th[ mrank[i] ]= h[i]; buildst(len-1); int m; long long ans1=0,ans2=0; scanf("%d",&m); int x,y,tmp; scanf("%d%d",&x,&y); ans1+=y-x; ans2+=y-x; save[1]=0; for(int i=2;i<=m;i++) { int tx,ty; scanf("%d%d",&tx,&ty); ans1+=ty-tx; int cnt; if(tx==x) cnt=len-1-tx; else cnt=cal(mrank[tx],mrank[x]); save[i]=min(ty-tx,min(y-x,cnt)); ans2+=ty-tx-save[i]; x=tx; y=ty; } ans1+=m; ans2+=m+m; for(int i=1;i<=m;i++) { ans2++; save[i]/=10; while(save[i]) { ans2++; save[i]/=10; } } cout<<ans1<<" "<<ans2<<endl; } return 0; }
标签:des blog http io os ar java for strong
原文地址:http://www.cnblogs.com/chenhuan001/p/4017853.html