• Distinct Substrings (spoj694)(后缀数组)


    核心:每一个后缀的每一个前缀都是一个子串

    相邻后缀的lcp的值是就是重复子串的个数

    用所有的子串减去sigma(height)就行了

     1 #include"bits/stdc++.h"
     2 using namespace std;
     3 #define clr(x) memset(x,0,sizeof(x))
     4 
     5 int T;
     6 char a[2000];
     7 int n,m;
     8 int x[2000],y[2000],c[2000];
     9 int sa[2000];
    10 int rk[2000];
    11 int ht[2000];
    12 
    13 inline void SA()
    14 {
    15    //cout<<"%^("<<endl;
    16 
    17    // cout<<n<<" "<<m<<endl;
    18  //cout<<a+1<<endl;
    19    /* memset(c,0,sizeof c);
    20     memset(x,0,sizeof x);
    21     memset(y,0,sizeof y);*/
    22     clr(c);
    23     clr(x);
    24     clr(y);
    25 
    26 
    27    for (int i=1;i<=n;i++) ++c[x[i] = a[i]-'A'];
    28    for (int i=1;i<=m;i++) c[i]+=c[i-1];
    29    for (int i=n;i;i--) sa[c[x[i]]--] = i;
    30 
    31    for (int k=1;k<=n;k*=2)
    32    {
    33 
    34       int num = 0;
    35       for (int i=n-k+1;i<=n;i++) y[++num] = i;
    36       for (int i=1;i<=n;i++) if (sa[i]>k) y[++num] = sa[i]-k;
    37       memset(c,0,sizeof c);
    38       for (int i=1;i<=n;i++) ++c[x[y[i]]];
    39       for (int i=1;i<=m;i++) c[i]+=c[i-1];
    40       for (int i=n;i;i--) sa[c[x[y[i]]]--] = y[i],y[i]=0;
    41       num=1;
    42       swap(x,y);
    43       x[sa[1]]=1;
    44 
    45       for (int i=2;i<=n;i++)
    46       {
    47         x[sa[i]]=(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k])?num:++num;
    48       }
    49 
    50       if (num==n) break;
    51       m=num;
    52 
    53 
    54    }
    55 
    56    for (int i=1;i<=n;i++) rk[sa[i]] = i;
    57    int k = 0;
    58 
    59    for (int i=1;i<=n;i++)
    60    {
    61       if (rk[i]==1) continue;
    62       if (k) k--;
    63       int j =sa[rk[i]-1];
    64 
    65 
    66       while (a[i+k]==a[j+k]&&i+k<=n&&j+k<=n) k++;
    67 
    68       ht[rk[i]] = k;
    69    }
    70 
    71 //
    72    //  for (int i=1;i<=n;i++ ) cout<<ht[i]<<" ";cout<<endl;
    73   // /   / for (int i=1;i<=n;i++) cout<<sa[i]<<" ";cout<<endl;
    74 
    75 
    76 }
    77 
    78 
    79 
    80 int main()
    81 {
    82   cin>>T;
    83   while (T--)
    84   {
    85 
    86     m=233;
    87     cin>>a+1;
    88     n = strlen(a+1);
    89     SA();
    90 
    91   int ans = n*(n+1)/2;
    92   for (int i=1;i<=n;i++ ) ans -= ht[i];
    93   cout<<ans<<endl;
    94 
    95 
    96 
    97   }
  • 相关阅读:
    topcoder srm 320 div1
    topcoder srm 325 div1
    topcoder srm 330 div1
    topcoder srm 335 div1
    topcoder srm 340 div1
    topcoder srm 300 div1
    topcoder srm 305 div1
    topcoder srm 310 div1
    topcoder srm 315 div1
    如何统计iOS产品不同渠道的下载量?
  • 原文地址:https://www.cnblogs.com/zhangbuang/p/10283243.html
Copyright © 2020-2023  润新知