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;
    }

     

  • 相关阅读:
    HBASE学习笔记(一)
    模板:循环数据库表
    where(泛型类型约束)
    如何很好的使用Linq的Distinct方法
    Sql自定义表类型批量导入数据
    Linq select 语法
    JTemplate学习(四)
    JTemplate学习(三)
    JTemplate学习(二)
    正则表达式学习
  • 原文地址:https://www.cnblogs.com/rrsb/p/8325270.html
Copyright © 2011-2022 走看看