P2463 [SDOI2008]Sandy的卡片
套路都差不多,都是差分后二分答案找lcp。只是这题要把多个串拼接起来成为一个大串,中间用某些值域中没有的数字相隔(最好间隔符都不一样想想为什么),排序后在二分答案,开个栈统计即可(保证单次check复杂度O(N))。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=120000+7;//m<=101不是m<=100大小没算好坑死我了 5 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;} 6 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;} 7 inline int read(){ 8 int f=0,x=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1; 9 while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();return f?-x:x; 10 } 11 int a[N],pos[N],bin[N],vis[N],tot; 12 int n,l,x,ans,tmp,mid,L,R=100; 13 14 int sa[N],h[N],cnt[N],y[N],rk[N],p,m; 15 inline void suffix_sort(){m=5002; 16 for(register int i=1;i<=tot;++i)++cnt[rk[i]=a[i]]; 17 for(register int i=1;i<=m;++i)cnt[i]+=cnt[i-1]; 18 for(register int i=tot;i;--i)sa[cnt[rk[i]]--]=i; 19 for(register int k=1;k<tot;k<<=1,p=0){ 20 for(register int i=tot-k+1;i<=tot;++i)y[++p]=i; 21 for(register int i=1;i<=tot;++i)if(sa[i]>k)y[++p]=sa[i]-k; 22 for(register int i=1;i<=m;++i)cnt[i]=0; 23 for(register int i=1;i<=tot;++i)++cnt[rk[y[i]]]; 24 for(register int i=1;i<=m;++i)cnt[i]+=cnt[i-1]; 25 for(register int i=tot;i;--i)sa[cnt[rk[y[i]]]--]=y[i]; 26 swap(rk,y);rk[sa[1]]=p=1; 27 for(register int i=2;i<=tot;++i)rk[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?p:++p; 28 if(p==tot)break;m=p; 29 }p=0; 30 for(register int i=1;i<=tot;h[rk[i]]=p,p?--p:1,++i)while(a[i+p]==a[sa[rk[i]-1]+p]&&++p); 31 } 32 33 inline int check(int k){ 34 for(register int i=1;a[sa[i]]<=4000;++i){ 35 if(h[i]<k){while(x)vis[bin[x--]]=0;} 36 if(!vis[pos[sa[i]]])vis[pos[sa[i]]]=1,bin[++x]=pos[sa[i]]; 37 if(x==n)return 1; 38 } 39 return 0; 40 } 41 42 int main(){//freopen("tmp.in","r",stdin); 43 n=read(); 44 for(register int i=1;i<=n;++i){ 45 l=read();a[++tot]=read();pos[tot]=i; 46 for(register int j=2;j<=l;++j)a[++tot]=read(),a[tot-1]=a[tot]-a[tot-1]+2000,pos[tot]=i; 47 a[tot]=i+4000; 48 } 49 suffix_sort(); 50 while(L<=R){ 51 mid=L+R>>1; 52 if(check(mid))ans=mid,L=mid+1; 53 else R=mid-1; 54 } 55 printf("%d ",ans+1); 56 return 0; 57 }