zoukankan      html  css  js  c++  java
  • Luogu P4070 [SDOI2016]生成魔咒

    题意:求本质不同的子串数。

    (SA)

    (SAM+DP)

    答案即为路径条数。

    我们设 (f[u]) 表示从 (u) 出发的路径条数:(f[u]=1+sum_{(u,v,ch)} f[v]) ,其中 (1) 代表空串。

    最后答案即为 (f[0]-1)

    (SAM+parent树)

    每个子串只会出现一次,并且每个点的 (sz) 即为 (maxlen[u]-minlen[u])

    答案为 (sum len[u]-len[fa[u]])

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<unordered_map>
    #define R register int
    #define ll long long
    using namespace std;
    namespace Luitaryi {
    inline int g() { R x=0,f=1;
      register char s; while(!isdigit(s=getchar())) f=s=='-'?-1:f;
      do x=x*10+(s^48); while(isdigit(s=getchar())); return x*f;
    } 
    const int N=100010;
    int n,tot=1,lst=1;
    int fa[N],len[N];
    ll ans;
    unordered_map<int,int> c[N];
    inline void add(int ch) {
      R p=lst,np=lst=++tot;
      len[np]=len[p]+1;
      for(;p&&!c[p].count(ch);p=fa[p]) c[p][ch]=np;
      if(!p) fa[np]=1;
      else {
        R q=c[p][ch];;
        if(len[q]==len[p]+1) fa[np]=q;
        else {
          R nq=++tot;
          c[nq]=c[q];
          fa[nq]=fa[q],len[nq]=len[p]+1;
          fa[q]=fa[np]=nq;
          for(;p&&c[p].count(ch)&&c[p][ch]==q;p=fa[p]) c[p][ch]=nq;
        }
      }
      printf("%lld
    ",ans+=len[np]-len[fa[np]]);
    }
    inline void main() {
      n=g();
      for(R i=1;i<=n;++i) add(g());
    }
    } signed main() {Luitaryi::main(); return 0;}
    

    2019.01.09

  • 相关阅读:
    sqlserver2005系统表、视图研究2
    SQLServer2005新分页方法
    应该多了解一些工具
    关于SQLServer的小技巧
    EasyUI DataGrid使用Json加载不了数据
    js跨域及解决方案
    关于Master Page的css和js文件引用问题
    嵌套母版页
    SSMS获取存储过程中的返回值和output值
    静态构造函数
  • 原文地址:https://www.cnblogs.com/Jackpei/p/12177391.html
Copyright © 2011-2022 走看看