• [bzoj3238]差异


    对于前两个sigma,可以直接处理,相当于求$\sum\limits_{1\leq i<j\leq n}lcp(i,j)$

    倒序字符串后的parent树(后缀树),lcp(i,j)其实就是i这个前缀和j这个前缀parent树上的lca,则对于任意一个节点,考虑其为lca的方案,就是任意两个儿子中有多少个前缀的乘积,树形dp即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 500005
     4 int V,last,a[N<<1],sz[N<<1],sum[N<<1],id[N<<1],len[N<<1],fa[N<<1],ch[N<<1][31];
     5 long long ans;
     6 char s[N];
     7 void add(int c){
     8     int p=last,np=last=++V;
     9     len[np]=len[p]+1;
    10     sum[np]=sz[np]=1;
    11     for(;(p)&&(!ch[p][c]);p=fa[p])ch[p][c]=V;
    12     if (!p)fa[np]=1;
    13     else{
    14         int q=ch[p][c];
    15         if (len[q]==len[p]+1)fa[np]=q;
    16         else{
    17             int nq=++V;
    18             len[nq]=len[p]+1;
    19             memcpy(ch[nq],ch[q],sizeof(ch[q]));
    20             fa[nq]=fa[q];
    21             fa[q]=fa[np]=nq;
    22             for(;(p)&&(ch[p][c]==q);p=fa[p])ch[p][c]=nq;
    23         }
    24     }
    25 }
    26 int main(){
    27     scanf("%s",s);
    28     int l=strlen(s);
    29     V=last=1;
    30     for(int i=l-1;i>=0;i--)add(s[i]-'a');
    31     for(int i=1;i<=V;i++)a[len[i]]++;
    32     for(int i=0;s[i];i++)a[i+1]+=a[i];
    33     for(int i=1;i<=V;i++)id[a[len[i]]--]=i;
    34     for(int i=V;i;i--)sz[fa[id[i]]]+=sz[id[i]];
    35     for(int i=V;i;i--){
    36         ans+=1LL*sum[fa[id[i]]]*sz[id[i]]*len[fa[id[i]]];
    37         sum[fa[id[i]]]+=sz[id[i]];
    38     }
    39     printf("%lld",1LL*l*(l-1)*(l+1)/2-2*ans);
    40 }
    View Code
  • 相关阅读:
    Linux配置NTP服务器,时间同步
    个人博客:有态度的HBase/Spark/BigData
    solr 6.2.1环境搭建
    大牛博客!Spark / Hadoop / Kafka / HBase / Storm
    hive 数据导出三种方式
    hive 分区表
    hive 创建orc表
    Tomcat中JVM内存溢出及合理配置及maxThreads如何配置(转)
    oracle 日期时间函数
    02: linux命令bak
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11249773.html
Copyright © 2020-2023  润新知