• dtoi2680「SDOI2016」生成魔咒


    题意:

         魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示。例如可以将魔咒字符 $ 1 $、$ 2 $ 拼凑起来形成一个魔咒串 $ [1, 2] $。

         一个魔咒串 $ S $ 的非空子串被称为魔咒串 $ S $ 的生成魔咒。

         例如 $ S = [1, 2, 1] $ 时,它的生成魔咒有 $ [1] $、$ [2] $、$ [1, 2] $、$ [2, 1] $、$ [1, 2, 1] $ 五种。$ S = [1, 1, 1] $ 时,它的生成魔咒有 $ [1] $、$ [1, 1] $、$ [1, 1, 1] $ 三种。

         最初 $ S $ 为空串。共进行 $ n $ 次操作,每次操作是在 $ S $ 的结尾加入一个魔咒字符。每次操作后都需要求出,当前的魔咒串 $ S $ 共有多少种生成魔咒。

         对于 $ 100\% $ 的数据,$ 1 leq n leq 100000 $。

         用来表示魔咒字符的数字 $ x $ 满足 $ 1 leq x leq 10 ^ 9 $。

    题解:

         考虑使用后缀自动机,对于第 $i$ 个字符的加入,显然会产生一些区间 $[l,i]$ 作为答案的贡献,$l$的范围一定介于 $1$ 与某个数字之间。思考后缀自动机的本质,后缀自动机的每一个节点,表示相同的“结尾集合”的所有子串,对于每一个子串,他必然在字符串中出现至少 $1$ 次,而每一次出现的右端点的集合就称之为“结尾集合”(这似乎只有我这么叫)。那么在这题中,$[1,i]$ 一定只出现了 $1$ 次,那么,与他所在同一个节点的所有字符串,也是只出现了 $1$ 次,且恰好是新出现的。

         所以这题就很容易了,每次答案的增加量都是新建节点的 $maxlen$ 减去它父亲的 $maxlen$,不过这题值域较大,可以用 $map$ 维护。

    #include<cstdio>
    #include<map>
    #include<algorithm>
    #include<cstdlib>
    using namespace std;
    int n,cur=1,cnt=1,last,fa[200002],dis[200002];
    long long ans;
    map<int,int>ch[200002];
    void build(int c,int id){
        last=cur;cur=++cnt;
        int p=last;dis[cur]=id;
        for (;p&&!ch[p].count(c);p=fa[p])ch[p][c]=cur;
        if (!p)fa[cur]=1; 
        else
        {
            int q=ch[p][c];
            if (dis[q]==dis[p]+1)fa[cur]=q;
            else
            {
                int nt=++cnt;dis[nt]=dis[p]+1;
                ch[nt]=ch[q];
                fa[nt]=fa[q];fa[q]=fa[cur]=nt;
                for (;ch[p].count(c)&&ch[p][c]==q;p=fa[p])ch[p][c]=nt;
            }
        }
    }
    int main()
    {
        scanf("%d",&n);int nw=1;
        for (int i=1;i<=n;i++)
        {
            int a;scanf("%d",&a);
            build(a,i);nw=ch[nw][a];
            ans+=dis[nw]-dis[fa[nw]];
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    using 关键字在 C++ 中的几种用法
    Chromium 修改图片资源
    SAM&广义SAM
    Burnside和Polya
    笔记:杜教筛
    笔记:莫比乌斯反演
    Miller-Rabin
    点分治
    虚树
    计算几何
  • 原文地址:https://www.cnblogs.com/1124828077ccj/p/14409807.html
Copyright © 2020-2023  润新知