1. 程式人生 > >【SPOJ220】Relevant Phrases of Annihilation(後綴數組,二分)

【SPOJ220】Relevant Phrases of Annihilation(後綴數組,二分)

spa std spoj lse map sign math vector mod

題意:技術分享圖片

n<=10,len<=1e4

思路:

技術分享圖片

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<string>
  4 #include<cmath>
  5 #include<iostream>
  6 #include<algorithm>
  7 #include<map>
  8 #include<set>
  9 #include<queue>
 10 #include<vector>
 11
using namespace std; 12 typedef long long ll; 13 typedef unsigned int uint; 14 typedef unsigned long long ull; 15 typedef pair<int,int> PII; 16 typedef vector<int> VI; 17 #define fi first 18 #define se second 19 #define MP make_pair 20 #define N 210000 21 #define MOD 1000000007 22 #define
eps 1e-8 23 #define pi acos(-1) 24 #define oo 1000000000 25 26 char ch[N]; 27 28 int n,i,s[N],sa[N],wa[N],wb[N],wc[N],wd[N],height[N],rank[N], 29 a[N],b[N],c[N],d[N],num[N],M; 30 31 int read() 32 { 33 int v=0,f=1; 34 char c=getchar(); 35 while(c<48||57<c) {if(c==-) f=-1
; c=getchar();} 36 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 37 return v*f; 38 } 39 40 bool cmp(int *r,int a,int b,int l) 41 { 42 return r[a]==r[b]&&r[a+l]==r[b+l]; 43 } 44 45 void getsa(int *r,int *sa,int n,int m) 46 { 47 int *x=wa,*y=wb,j,p; 48 for(i=0;i<n;i++) wc[x[i]=r[i]]++; 49 for(i=1;i<m;i++) wc[i]+=wc[i-1]; 50 for(i=n-1;i>=0;i--) sa[--wc[x[i]]]=i; 51 for(j=1,p=1;p<n;j*=2,m=p) 52 { 53 p=0; 54 for(i=n-j;i<n;i++) y[p++]=i; 55 for(i=0;i<n;i++) 56 if(sa[i]>=j) y[p++]=sa[i]-j; 57 for(i=0;i<n;i++) wd[i]=x[y[i]]; 58 for(i=0;i<m;i++) wc[i]=0; 59 for(i=0;i<n;i++) wc[wd[i]]++; 60 for(i=1;i<m;i++) wc[i]+=wc[i-1]; 61 for(i=n-1;i>=0;i--) sa[--wc[wd[i]]]=y[i]; 62 swap(x,y); 63 p=1; x[sa[0]]=0; 64 for(i=1;i<n;i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; 65 } 66 } 67 68 void getheight(int *r,int *sa,int n) 69 { 70 int i,j,k=0; 71 for(i=1;i<=n;i++) rank[sa[i]]=i; 72 for(i=0;i<n;height[rank[i++]]=k) 73 { 74 if(k) k--; 75 j=sa[rank[i]-1]; 76 while(r[i+k]==r[j+k]) k++; 77 } 78 } 79 80 void init() 81 { 82 memset(s,0,sizeof(s)); 83 memset(sa,0,sizeof(sa)); 84 memset(wa,0,sizeof(wa)); 85 memset(wb,0,sizeof(wb)); 86 memset(wc,0,sizeof(wc)); 87 memset(wd,0,sizeof(wd)); 88 memset(height,0,sizeof(height)); 89 memset(rank,0,sizeof(rank)); 90 } 91 92 bool isok(int K) 93 { 94 int i=1; 95 while(i<n) 96 { 97 i++; 98 if(height[i]>=K) 99 { 100 int st=i; 101 while(i<=n&&height[i]>=K) i++; 102 if(st<=i-1) 103 { 104 int ed=i-1; 105 for(int j=1;j<=M;j++) 106 { 107 b[j]=0; 108 c[j]=oo; 109 d[j]=-oo; 110 } 111 for(int j=st-1;j<=ed;j++) 112 { 113 int t=num[sa[j]]; 114 b[t]++; 115 c[t]=min(c[t],sa[j]); 116 d[t]=max(d[t],sa[j]); 117 } 118 int flag=1; 119 for(int j=1;j<=M;j++) 120 { 121 if(b[j]<2){flag=0; break;} 122 if(d[j]-c[j]<K){flag=0; break;} 123 } 124 if(flag) return 1; 125 } 126 } 127 } 128 return 0; 129 } 130 131 int main() 132 { 133 freopen("spoj220.in","r",stdin); 134 freopen("spoj220.out","w",stdout); 135 int cas; 136 scanf("%d",&cas); 137 while(cas--) 138 { 139 init(); 140 scanf("%d",&M); 141 n=-1; 142 for(int i=1;i<=M;i++) 143 { 144 scanf("%s",ch); 145 int t=strlen(ch); 146 for(int j=0;j<t;j++) 147 { 148 s[++n]=ch[j]-a+20; 149 num[n]=i; 150 } 151 s[++n]=i; 152 num[n]=0; 153 } 154 getsa(s,sa,n+1,100); 155 getheight(s,sa,n); 156 // printf("1\n"); 157 int L=1; 158 int R=10000; 159 int last=0; 160 while(L<=R) 161 { 162 int mid=(L+R)>>1; 163 if(isok(mid)){last=mid; L=mid+1;} 164 else R=mid-1; 165 } 166 printf("%d\n",last); 167 } 168 return 0; 169 } 170

【SPOJ220】Relevant Phrases of Annihilation(後綴數組,二分)