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

    我们建SAM,在SAM上跑DP:(SAM不会点这里

    我们发现柿子的前半部分很好统计,那么我们只要搞后半部分。

    我们反向建SAM,fa上的LCA就是其反串的前缀的后缀(原串的后缀的前缀)。

    #include<bits/stdc++.h>
    #define N 1000017
    #define deg  
    using namespace std;
    struct S{ int val,ch[26],fa;}T[N];
    int tot=1,last=1,np,q,nq,cnt[N],c[N>>1],len,id[N],x,sum[N]; 
    char ch[N>>1];
    long long ans;
    inline void Sam(int x){
        np=++tot; T[np].val=T[last].val+1;
        for (;last&&!T[last].ch[x];last=T[last].fa) T[last].ch[x]=np;
        if (!last) T[np].fa=1; else {
            q=T[last].ch[x];
            if (T[last].val+1==T[q].val) T[np].fa=q;
            else { 
               nq=++tot; T[nq]=T[q];T[nq].val=T[last].val+1; 
               T[q].fa=T[np].fa=nq;
               for (;last&&T[last].ch[x]==q;last=T[last].fa) T[last].ch[x]=nq;
            }
        }  last=np; sum[last]=cnt[last]=1;
    }
    
    int main () {
    //   freopen("a.in","r",stdin);
       scanf("%s",ch+1); len=strlen(ch+1);
       for (int i=len;i;i--)
        Sam(ch[i]-'a');
       for (int i=1;i<=tot;i++) c[T[i].val]++;
       for (int i=1;i<=len;i++) c[i]+=c[i-1];
       for (int i=1;i<=tot;i++) id[c[T[i].val]--]=i;
       for (int i=tot;i;i--) cnt[T[id[i]].fa]+=cnt[id[i]];
       for (int i=tot;i;i--) {
            x=id[i];
            ans+=1ll*sum[T[x].fa]*cnt[x]*T[T[x].fa].val;
            sum[T[x].fa]+=cnt[x];
       }
       deg("%lld
    ",ans);
       printf("%lld
    ",1ll*len*(len-1)*(len+1)/2-ans*2);
       return 0;
    }

     

  • 相关阅读:
    python的gui库tkinter
    python图像处理库Pillow基本使用方法
    github配置SSH proxy
    python的pandas库读取csv
    学习app开发思路
    shell脚本中四则运算
    shell脚本实例三
    shell脚本实例二
    shell脚本实例一
    LINUX系统下的shell命令---grep、sed、awk
  • 原文地址:https://www.cnblogs.com/rrsb/p/8325270.html
Copyright © 2011-2022 走看看