yicongli

LG3966

Mar 7th, 2019
553
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.37 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. #define gc c=getchar()
  6. #define r(x) read(x)
  7. #define ll long long
  8.  
  9. template<typename T>
  10. inline void read(T&x){
  11.     x=0;T k=1;char gc;
  12.     while(!isdigit(c)){if(c=='-')k=-1;gc;}
  13.     while(isdigit(c)){x=x*10+c-'0';gc;}x*=k;
  14. }
  15.  
  16. const int N=1e6+207;
  17.  
  18. namespace Suffix_Array{
  19.     int n,m;
  20.    
  21.     int SA[N];
  22.     int Rank[N];
  23.     int tmp[N];
  24.     int cnt[N];
  25.    
  26.     inline void Qsort(int *a,int *b){
  27.         for(int i=1;i<=m;++i)cnt[i]=0;
  28.         for(int i=1;i<=n;++i)cnt[a[i]]++;
  29.         for(int i=1;i<=m;++i)cnt[i]+=cnt[i-1];
  30.         for(int i=n;i>=1;--i)SA[cnt[a[b[i]]]--]=b[i];
  31.     }
  32.    
  33.     inline void GetSA(int *s,int len){
  34.         n=len,m=300;
  35.         for(int i=1;i<=n;++i)Rank[i]=s[i];
  36.         for(int i=1;i<=n;++i)tmp[i]=i;
  37.         Qsort(Rank,tmp);
  38.         for(int l=1,p=0;p<n;l<<=1){
  39.             p=0;
  40.             for(int i=1;i<=l;++i)tmp[++p]=n-i+1;
  41.             for(int i=1;i<=n;++i)if(SA[i]>l)tmp[++p]=SA[i]-l;
  42.             Qsort(Rank,tmp);
  43.             memcpy(tmp+1,Rank+1,n<<2);
  44.             p=Rank[SA[1]]=1;
  45.             for(int i=2;i<=n;++i){
  46.                 if(tmp[SA[i]]!=tmp[SA[i-1]]||tmp[SA[i]+l]!=tmp[SA[i-1]+l])++p;
  47.                 Rank[SA[i]]=p;
  48.             }
  49.             m=p;
  50.         }
  51.     }
  52.    
  53.     int Hight[N];
  54.    
  55.     inline void GetHight(int *s){
  56.         for(int i=1,p=0;i<=n;++i){
  57.             int j=SA[Rank[i]-1];
  58.             if(p)--p;
  59.             while(s[i+p]==s[j+p]&&p<n)++p;
  60.             Hight[Rank[i]]=p;
  61.         }
  62.     }
  63.    
  64.     int st[N][20];
  65.     int LG[N];
  66.    
  67.     inline void RMQinit(){
  68.         for(int i=1;i<=n;++i)st[i][0]=Hight[i];
  69.         for(int i=2;i<=n;++i)LG[i]=LG[i>>1]+1;
  70.         for(int i=1;i<=LG[n];++i){
  71.             for(int j=1;j+(1<<i)-1<=n;++j){
  72.                 st[j][i]=min(st[j][i-1],st[j+(1<<(i-1))][i-1]);
  73.             }
  74.         }
  75.     }
  76.    
  77.     inline int lcp(int l,int r){
  78.         int x=LG[r-l];
  79.         return min(st[l+1][x],st[r-(1<<x)+1][x]);
  80.     }
  81.    
  82.     inline int query(int x,int len){
  83.         x=Rank[x];
  84.         /*
  85.         int l=x,r=x+1;
  86.         while(Hight[l]>=len)--l;
  87.         while(Hight[r]>=len)++r;--r;
  88.         return r-l+1;
  89.         */
  90.        
  91.         int l=1,r=x,mid,ans=x,ret=0;
  92.         while(l<=r){
  93.             mid=(l+r)>>1;
  94.             if(lcp(mid,x)>=len)r=mid-1,ans=mid;
  95.             else l=mid+1;
  96.         }
  97.         ret+=x-ans;
  98.         ans=l=x,r=n;
  99.         while(l<=r){
  100.             mid=(l+r)>>1;
  101.             if(lcp(x,mid)>=len)l=mid+1,ans=mid;
  102.             else r=mid-1;
  103.         }
  104.         ret+=ans-x;
  105.         return ret+1;
  106.        
  107.     }
  108. }
  109.  
  110. char str[N];
  111. int s[N];
  112. int pos[N];
  113. int len[N];
  114.  
  115. int main(){
  116.     int n,p=0;r(n);
  117.     for(int i=1;i<=n;++i){
  118.         scanf("%s",str);
  119.         pos[i]=p+1;
  120.         len[i]=strlen(str);
  121.         for(int j=0;j<len[i];++j){
  122.             s[++p]=str[j]-'a'+1;
  123.         }
  124.         s[++p]=26+i;
  125.     }
  126.     Suffix_Array::GetSA(s,p);
  127.     Suffix_Array::GetHight(s);
  128.     Suffix_Array::RMQinit();
  129.     for(int i=1;i<=n;++i){
  130.         printf("%d\n",Suffix_Array::query(pos[i],len[i]));
  131.     }
  132. }
Advertisement
Add Comment
Please, Sign In to add comment