UVA 11739 Giving Candies

求最大的公共前缀;

用后缀数组做;

其实暴力也可以过;

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #define maxn 2009
  5 using namespace std;
  6 
  7 int s[maxn];
  8 int sa[maxn],t[maxn],t2[maxn],c[maxn],n;
  9 
 10 void build_sa(int m)
 11 {
 12     int *x=t,*y=t2;
 13     for(int i=0; i<m; i++)c[i]=0;
 14     for(int i=0; i<n; i++)c[x[i]=s[i]]++;
 15     for(int i=1; i<m; i++)c[i]+=c[i-1];
 16     for(int i=n-1; i>=0; i--)sa[--c[x[i]]]=i;
 17     for(int k=1; k<=n; k<<=1)
 18     {
 19         int p=0;
 20         for(int i=n-k; i<n; i++)y[p++]=i;
 21         for(int i=0; i<n; i++)if(sa[i]>=k)y[p++]=sa[i]-k;
 22         for(int i=0; i<m; i++)c[i]=0;
 23         for(int i=0; i<n; i++)c[x[y[i]]]++;
 24         for(int i=0; i<m; i++)c[i]+=c[i-1];
 25         for(int i=n-1; i>=0; i--)sa[--c[x[y[i]]]]=y[i];
 26         swap(x,y);
 27         p=1;
 28         x[sa[0]]=0;
 29         for(int i=1; i<n; i++)
 30             x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
 31         if(p>=n)break;
 32         m=p;
 33     }
 34 }
 35 
 36 int rank[maxn],height[maxn];
 37 void getheight()
 38 {
 39     int k=0;
 40     for(int i=0; i<n; i++)rank[sa[i]]=i;
 41     for(int i=0; i<n; i++)
 42     {
 43         if(k)k--;
 44         int j=sa[rank[i]-1];
 45         while(s[i+k]==s[j+k])k++;
 46         height[rank[i]]=k;
 47     }
 48 }
 49 
 50 bool check(int mid)
 51 {
 52     int mi=99999,ma=-1;
 53     for(int i=1; i<n; i++)
 54     {
 55         if(height[i]>=mid)
 56         {
 57             mi=min(mi,sa[i]);
 58             ma=max(ma,sa[i]);
 59         }
 60         else
 61         {
 62             if(ma-mi>=mid)return 1;
 63             mi=ma=sa[i];
 64         }
 65     }
 66     if(ma-mi>=mid)return 1;
 67     return 0;
 68 }
 69 
 70 bool isbad[150];
 71 char bad[1005],good[1005];
 72 int main()
 73 {
 74     int tt,r,ca=1;
 75     scanf("%d",&tt);
 76     getchar();
 77     while(tt--)
 78     {
 79         memset(isbad,0,sizeof isbad);
 80         gets(good);
 81         gets(bad);
 82         int l=strlen(bad);
 83         for(int i=0; bad[i]!=''; i++)
 84             isbad[bad[i]]=1;
 85         n=strlen(good);
 86         while(n>0&&good[n-1]==' ')
 87         {
 88             good[n-1]='';
 89             --n;
 90         }
 91         int xx='z';
 92         for(int i=0; good[i]!=''; i++)
 93         {
 94             if(isbad[good[i]])s[i]=xx++;
 95             else s[i]=good[i];
 96         }
 97         s[n]=0;
 98         if (n<=1)
 99         {
100             printf("Case #%d: 0
",ca++);
101             continue;
102         }
103         n++;
104         build_sa(xx+3);
105         getheight();
106         l=0,r=n>>1;
107         while(l<=r)
108         {
109             int mid=(l+r)>>1;
110             if(check(mid))l=mid+1;
111             else r=mid-1;
112         }
113         printf("Case #%d: %d
",ca++,r);
114     }
115     return 0;
116 }
View Code
原文地址:https://www.cnblogs.com/yours1103/p/3422405.html