hdu 4691 Front compression

后缀数组的简单题吧。

 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\n",orgin,compress);
94     }
95     return 0;
96 }

 

posted @ 2013-11-01 15:50  sooflow  阅读(142)  评论(0编辑  收藏  举报