poj 3294 Life Forms 后缀数组

题意:给n个字符串,求一个最长的子串至少出现在[n/2+1]个字符串中

思路:后缀数组 把所有字串连一起,并用不同的字符隔开 二分

P.S. 1. 我的程序C++WA,G++ AC

   2. 为什么char的上界是127啊

  1 #include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 using namespace std;
5 #define MAXN 110000
6 int n,m;
7 int suffix_array[MAXN];
8 int rank[2*MAXN],oldrank[2*MAXN];
9 int cnt[MAXN],tmp[MAXN];
10 int height[MAXN];
11 int a[MAXN];
12 int mark[MAXN];
13 void SuffixArray()
14 {
15 int memo[300];
16 suffix_array[0]=0;
17 memset(memo,0,sizeof(memo));
18 memset(rank,0,sizeof(rank));
19 memset(oldrank,0,sizeof(oldrank));
20 int i,l;
21 for(i=1;i<=n;i++) memo[a[i]]=1;
22 for(i=1;i<300;i++) memo[i]+=memo[i-1];
23 for(i=1;i<=n;i++) rank[i]=memo[a[i]];
24 for(l=1;l<=n;l*=2)
25 {
26 memset(cnt,0,sizeof(cnt));
27 for(i=1;i<=n;i++) cnt[rank[i+l]]++;
28 for(i=1;i<=n;i++) cnt[i]+=cnt[i-1];
29 for(i=1;i<=n;i++) tmp[cnt[rank[i+l]]--]=i;
30
31 memset(cnt,0,sizeof(cnt));
32 for(i=1;i<=n;i++) cnt[rank[tmp[i]]]++;
33 for(i=1;i<=n;i++) cnt[i]+=cnt[i-1];
34 for(i=n;i>0;i--) suffix_array[cnt[rank[tmp[i]]]--]=tmp[i];
35
36 memcpy(oldrank,rank,sizeof(rank));
37 rank[suffix_array[1]]=1;
38 int k=1;
39 for(i=2;i<=n;i++)
40 {
41 int x=suffix_array[i-1],y=suffix_array[i];
42 if(oldrank[x]!=oldrank[y]||oldrank[x+l]!=oldrank[y+l]) k++;
43 rank[y]=k;
44 }
45 if(k==n) break;
46 }
47 }
48 void LCP()
49 {
50 int i,j,k=0;
51 for(i=1;i<=n;i++)
52 {
53 if(rank[i]==n)
54 {
55 height[n]=k=0; continue;
56 }
57 j=suffix_array[rank[i]+1];
58 k=max(k-1,0);
59 while(a[j+k]==a[i+k]) k++;
60 height[rank[i]]=k;
61 }
62 height[0]=-1; mark[0]=m+1;
63 }
64 bool check(int mid,bool w)
65 {
66 bool use[102];
67 memset(use,0,sizeof(use));
68 int k=1;
69 int i,j;
70 for(i=1;i<=n;i++)
71 {
72 if(a[suffix_array[i-1]]>'z') break;
73 if(height[i-1]>=mid)
74 {
75 if(use[mark[suffix_array[i]]]==0)
76 {
77 use[mark[suffix_array[i]]]=1;
78 k++;
79 }
80 }
81 else
82 {
83 if(k>m/2)
84 {
85 if(w==0) return 1;
86 for(j=suffix_array[i-1];j<=suffix_array[i-1]+mid-1;j++)
87 printf("%c",a[j]);
88 printf("\n");
89 }
90 memset(use,0,sizeof(use));
91 k=1; use[mark[suffix_array[i]]]=1;
92 }
93
94 }
95 if(w==0)
96 return 0;
97 printf("\n");
98 }
99 int binary()
100 {
101 int left=0,right=n+1;
102 int mid;
103 while(left<right)
104 {
105 mid=(left+right)/2;
106 if(check(mid,0)) left=mid;
107 else right=mid;
108 if(right-left==1) return left;
109 }
110 }
111 int main()
112 {
113 char c[1001];
114 scanf("%d",&m);
115 int i,j,l,k;
116 int maxl;
117 while(m!=0)
118 {
119 memset(a,0,sizeof(a));
120 j=1;
121 for(i=1;i<=m;i++)
122 {
123 scanf("%s",c);
124 l=strlen(c);
125 for(k=j;k<=l+j-1;k++)
126 {
127 mark[k]=i;
128 a[k]=c[k-j];
129 }
130 j=j+l; mark[j]=m+1; a[j]='z'+i;
131 j++;
132 }
133 if(m==1)
134 {
135 printf("%s\n\n",c);
136 scanf("%d",&m);
137 continue;
138 }
139 n=j-2;
140 SuffixArray();
141 LCP();
142 maxl=binary();
143 if(maxl!=0) check(maxl,1);
144 else printf("?\n\n");
145 scanf("%d",&m);
146 }
147 return 0;
148 }
149
150
151


答案

原文地址:https://www.cnblogs.com/myoi/p/2343835.html