zoukankan      html  css  js  c++  java
  • 4516: [Sdoi2016]生成魔咒

    4516: [Sdoi2016]生成魔咒

    链接

    题意:

      求本质不同的子串。

    分析:

      后缀数组或者SAM都可以。

      考虑SAM中每个点的可以表示的子串是一个区间min(S)~max(S),把每个点的这个区间加起来即可。

      字符集有点大,可以用map。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<cctype>
    #include<set>
    #include<queue>
    #include<vector>
    #include<map>
    using namespace std;
    typedef long long LL;
    
    inline int read() {
        int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    }
    
    const int N = 200005;
    map<int,int> ch[N];
    int fa[N], len[N], Index = 1, Last = 1;
    LL Ans;
    
    void extend(int c) {
        int np = ++Index, p = Last; 
        len[np] = len[p] + 1;
        for (; p && ch[p].find(c) == ch[p].end(); p = fa[p]) ch[p][c] = np;
        if (!p) fa[np] = 1;
        else {
            int Q = ch[p][c];
            if (len[Q] == len[p] + 1) fa[np] = Q;
            else {
                int NQ = ++Index;
                fa[NQ] = fa[Q];
                ch[NQ] = ch[Q];
                len[NQ] = len[p] + 1;
                fa[Q] = fa[np] = NQ;
                for (; p && ch[p].find(c) != ch[p].end() && ch[p][c] == Q; p = fa[p]) ch[p][c] = NQ;
            }
        }
        Last = np;
        Ans += len[np] - len[fa[np]]; // max(np)=len[np], min(np)=len[fa[p]] + 1
        printf("%lld
    ", Ans);
    }
    int main() {
        int n = read(); 
        for (int i = 1; i <= n; ++i) {
            int x = read();
            extend(x);
        }
        return 0;
    }
  • 相关阅读:
    Python2的object和type
    str函数
    关于Python IDLE reload(sys)后无法正常执行命令的原因
    str和unicode类
    https://www.zhihu.com/question/31110175
    Python 头部 #!/usr/bin/python 和 #!/usr/bin/env 的区别
    正则表达式
    StringBuffer类
    String类
    抽象类、接口作为方法返回值和参数
  • 原文地址:https://www.cnblogs.com/mjtcn/p/10367238.html
Copyright © 2011-2022 走看看