zoukankan      html  css  js  c++  java
  • bzoj 3238: [Ahoi2013]差异

    一看字符串 最长公共前缀,用后缀数组+单调栈搞搞就行啦。一定要注意long long 啊

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<queue>
     7 #include<algorithm>
     8 #include<vector>
     9 #define M 2000009
    10 #define EPS 1e-10
    11 #define MO 19650827
    12 #define ll long long
    13 using namespace std;
    14 ll read()
    15 {
    16     char ch=getchar();
    17     ll x=0,f=1;
    18     for(;ch<'0'||ch>'9';ch=getchar())
    19         if(ch=='-')
    20           f=-1;
    21     for(;ch>='0'&&ch<='9';ch=getchar())
    22         x=x*10+ch-'0';
    23     return x*f;
    24 }
    25 char ch[M];
    26 int K,sa[2][M],rk[2][M],v[M],a[M],p=1,q,n,H[M],t;
    27 ll ans,b[M],c[M];
    28 void work(int sa[M],int rk[M],int SA[M],int RK[M])
    29 {
    30   for(int i=1;i<=n;i++)
    31     v[rk[sa[i]]]=i;
    32   for(int i=n;i;i--)
    33     if(sa[i]>K)
    34       SA[v[rk[sa[i]-K]]--]=sa[i]-K;
    35   for(int i=n-K+1;i<=n;i++)
    36     SA[v[rk[i]]--]=i;
    37   for(int i=1;i<=n;i++)
    38     RK[SA[i]]=RK[SA[i-1]]+(rk[SA[i]]!=rk[SA[i-1]]||rk[SA[i]+K]!=rk[SA[i-1]+K]);
    39 }
    40 int main()
    41 {
    42    scanf("%s",ch+1);
    43    n=strlen(ch+1);
    44    for(int i=1;i<=n;i++)
    45      a[i]=ch[i]-'a'+1;
    46    for(int i=1;i<=n;i++)
    47      v[a[i]]++;
    48    for(int i=1;i<=26;i++)
    49      v[i]+=v[i-1];
    50    for(int i=1;i<=n;i++)
    51      sa[p][v[a[i]]--]=i;
    52    for(int i=1;i<=n;i++)
    53      rk[p][sa[p][i]]=rk[p][sa[p][i-1]]+(a[sa[p][i-1]]!=a[sa[p][i]]);
    54    K=1;
    55    for(;K<n;)
    56      {
    57        work(sa[p],rk[p],sa[q],rk[q]);
    58        swap(p,q);
    59        K<<=1;
    60      }
    61    K=0;
    62    for(int i=1;i<=n;i++)
    63      if(rk[p][i]==1)
    64        H[i]=0;
    65      else
    66        {
    67          int j=sa[p][rk[p][i]-1];
    68          for(;a[i+K]==a[j+K];K++);
    69          H[i]=K;
    70          if(K)
    71            K--;
    72        }
    73    ll su=0;
    74    for(int i=n-1;i;i--)
    75      {
    76         ll a1=H[sa[p][i+1]],s=1;
    77         for(;b[t]>a1;)
    78           {
    79             s+=c[t];
    80             su-=b[t]*c[t];
    81             t--;
    82            }
    83         su+=a1*s;
    84         if(b[t]==a1)
    85           c[t]+=s;
    86         else 
    87           {
    88             b[++t]=a1;
    89             c[t]=s;
    90           }
    91         ans+=su;
    92      }
    93    printf("%lld
    ",(ll)(n-1)*n*(n+1)/2-2*ans);
    94    return 0;
    95 }
    96 
  • 相关阅读:
    SharePoint 部署WebPart时 遇到"未能加载文件或程序集"错误
    SharePoint List ListItem 增删改 新增 修改 删除
    SharePoint 工作流错误日志
    asp.net网页中调用c#写的dll文件
    域帐号查询与更新
    POJ2386:Lake Counting(DFS) java程序员
    POJ2225:Asteroids!(BFS) java程序员
    POJ1019:Number Sequence(组合计数) java程序员
    POJ2446:Chessboard(二分匹配) java程序员
    POJ1018:Communication System(枚举+搜索剪枝) java程序员
  • 原文地址:https://www.cnblogs.com/xiw5/p/5651736.html
Copyright © 2011-2022 走看看