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



    Description

    Input

    一行,一个字符串S

    Output

    一行,一个整数,表示所求值

    Sample Input

    cacao

    Sample Output


    54

    HINT



    2<=N<=500000,S由小写英文字母组成


    前面的直接加就可以了。
    后面要减去的lcp就是品酒大会的第一问,排完序后用并查集搞一下就可以了。
    记得开LL

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<string>
     6 #include<algorithm>
     7 #include<map>
     8 #include<complex>
     9 #include<queue>
    10 #include<stack>
    11 #include<cmath>
    12 #include<set>
    13 #include<vector>
    14 #define maxn 500010
    15 #define LL long long
    16 using namespace std;
    17 char s[maxn];
    18 int n,k,sa[maxn],tmp[maxn],rk[maxn],fa[maxn];
    19 LL size[maxn];
    20 struct data{
    21   LL k;
    22   int id;
    23 }lcp[maxn];
    24 bool cmp(int i,int j){
    25   if(rk[i]!=rk[j]) return rk[i]<rk[j];
    26   else{
    27     int ri=i+k<=n?rk[i+k]:-1,rj=j+k<=n?rk[j+k]:-1;
    28     return ri<rj;
    29   }
    30 }
    31 void get_sa(){
    32   for(int i=0;i<=n;i++)
    33     sa[i]=i,rk[i]=i<n?s[i]:-1;
    34   for(k=1;k<=n;k*=2){
    35     sort(sa,sa+n+1,cmp);
    36     tmp[sa[0]]=0;
    37     for(int i=1;i<=n;i++)
    38       tmp[sa[i]]=tmp[sa[i-1]]+(cmp(sa[i-1],sa[i])?1:0);
    39     for(int i=0;i<=n;i++) rk[i]=tmp[i];
    40   }
    41 }
    42 void get_lcp(){
    43   for(int i=0;i<=n;i++) rk[sa[i]]=i;
    44   int h=0;
    45   lcp[0].k=0;
    46   for(int i=0;i<n;i++){
    47     int j=sa[rk[i]-1];
    48     if(h>0) h--;
    49     for(;j+h<n && i+h<n;h++)
    50       if(s[j+h]!=s[i+h]) break;
    51     lcp[rk[i]-1].k=h;
    52   }
    53 }
    54 bool CMP(const data &a,const data &b){
    55   return a.k>b.k;
    56 }
    57 int find(int x){
    58   if(fa[x]!=x) fa[x]=find(fa[x]);
    59   return fa[x];
    60 }
    61 int main(){
    62   scanf("%s",s);
    63   n=strlen(s);
    64   LL ans=0;
    65   for(int i=0;i<=n;i++) fa[i]=i,size[i]=1;
    66   get_sa();
    67   get_lcp();
    68   for(int i=1;i<n;i++) lcp[i].id=i;
    69   sort(lcp+1,lcp+n,CMP);
    70   for(int i=1;i<n;i++){
    71     int u=find(lcp[i].id),v=find(lcp[i].id+1);
    72     ans+=lcp[i].k*size[u]*size[v];
    73     fa[v]=u;
    74     size[u]+=size[v];
    75   }
    76   LL ans1=0;
    77   for(LL i=n;i>=1;i--)ans1+=i*(i-1)+i*(n-i);
    78   printf("%lld",ans1-2*ans);
    79   return 0;
    80 }
     
  • 相关阅读:
    移动安全
    Photoshop笔记
    ARMv7 与 ARMv8对比
    centos系统 网络配置
    视频大文件压缩
    开发者必备Linux命令
    开发者必备Docker命令
    文件服务器minio
    Java 图片Base64
    socket
  • 原文地址:https://www.cnblogs.com/pantakill/p/7197462.html
Copyright © 2011-2022 走看看