Poj1743 (后缀数组)

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<cmath>
  5 using namespace std;
  6 int ws[21111],wa[21111],wb[21111],sa[21111],x[21111],y[21111],h[21111],wv[21111],a[21111],b[21111],rank[21111];
  7 int cmp(int *r,int a,int b,int l){return (r[a]==r[b])&&(r[a+l]==r[b+l]);}
  8 void DA(int *r,int *sa,int n,int m)
  9 {
 10   int i,j,p,*x=wa,*y=wb,*t;
 11   for(i=0;i<m;i++)ws[i]=0;
 12   for(i=0;i<n;i++)ws[x[i]=r[i]]++;
 13   for(i=1;i<m;i++)ws[i]+=ws[i-1];
 14   for(i=n-1;i>=0;i--)sa[--ws[x[i]]]=i;
 15   for(j=1,p=1;p<n;j*=2,m=p)
 16   {
 17     for(p=0,i=n-j;i<n;i++)y[p++]=i;
 18     for(i=0;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j;
 19     for(i=0;i<n;i++)wv[i]=x[y[i]];
 20     for(i=0;i<m;i++)ws[i]=0;
 21     for(i=0;i<n;i++)ws[wv[i]]++;
 22     for(i=1;i<m;i++)ws[i]+=ws[i-1];
 23     for(i=n-1;i>=0;i--)sa[--ws[wv[i]]]=y[i];
 24     for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)
 25     x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
 26   }
 27 }
 28 void calheight(int n)
 29 {
 30   int i,j,k=0;
 31   memset(rank,0,sizeof(rank));
 32   for(i=1;i<n;i++)rank[sa[i]]=i;
 33   for(i=0;i<n;h[rank[i++]]=k)
 34   for(k?k--:0,j=sa[rank[i]-1];b[i+k]==b[j+k];)
 35   k++;
 36 }
 37 int solve(int o,int n)
 38 {
 39   int min,max,i;
 40   max=-0x7fffffff;
 41   min=0x7fffffff;
 42   for(i=0;i<=n;i++)
 43   {
 44     if(h[i]>=o)
 45     {
 46       if(sa[i]>max)max=sa[i];
 47       if(sa[i]<min)min=sa[i];
 48       if(max-min>=o)return 1;
 49     }
 50     else
 51     {
 52       max=-0x7fffffff;
 53       min=0x7fffffff;
 54       if(sa[i]>max)max=sa[i];
 55       if(sa[i]<min)min=sa[i];
 56     }
 57   }
 58   if(max-min>=o)return 1;
 59   return 0;
 60 }
 61 void ef(int low,int high,int n)
 62 {
 63   int mid;
 64   while(low<high-1)
 65   {
 66     mid=(low+high)/2;
 67     if(solve(mid,n)==1)
 68     {
 69       low=mid;
 70     }
 71     else
 72     {
 73       high=mid;
 74     }
 75   }
 76   if(low<4)printf("0
");
 77   else printf("%d
",low+1);
 78 }
 79 int main()
 80 { 83   int n,i,max,min;
 84   while(1)
 85   {
 86     memset(ws,0,sizeof(ws));
 87     memset(wa,0,sizeof(wa));
 88     memset(wb,0,sizeof(wb));
 89     memset(sa,0,sizeof(sa));
 90     memset(h,0,sizeof(h));
 91     memset(wv,0,sizeof(wv));
 92     scanf("%d",&n);
 93     if(n==0)break;
 94     for(i=1;i<=n;i++)scanf("%d",&a[i]);
 95     if(n<10)
 96     {
 97       printf("0
");
 98       continue;
 99     }
100     if(n==1)
101     {
102       printf("0
");
103       continue;
104     }
105     for(i=1;i<=n-1;i++)b[i-1]=a[i+1]-a[i]+90;
106     b[n-1]=0;
107     n--;
108     max=-0x7fffffff;
109     min=0x7fffffff;
110     DA(b,sa,n+1,256);
111     calheight(n+1);
112     max=-0x7fffffff;
113     min=0x7fffffff;
114     for(i=0;i<n;i++)
115     {
116       if(h[i]>max)max=h[i];
117       if(h[i]<min)min=h[i];
118     }
119     ef(0,n,n);
120   }
121   return 0;
122 }
原文地址:https://www.cnblogs.com/wjcwjc/p/4977909.html