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

    传送门

    心态崩了++

    后缀自动机板子题[考场上要是不会后缀自动机就崩了T^T]

    可以看出 每次答案的贡献就是和原来本质不同的子串数量

    根据SPOJ7258我们可以得到 本质不同的子串数量可以通过建出自动机 树形dp解决

    我们需要知道的就是 连向它的那个链

    就是我们建立自动机的时候的那个找的p

    直接求一下就好了

    另外的理解方式就是我们要求本质不同的前缀数量 那么就是parent树上len的定义 直接len[x]-len[fa]就是答案

    时间复杂度O(n)

    写完了调过样例交了一发WA 然后看到STD里开longlong了改了一发longlong又一发WA 然后心态崩掉 一点一点重推 最后发现 我输出没改 还是%d [手动再见]

    附代码。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<map>
    #define inf 20021225
    #define ll long long
    #define mxn 100010
    using namespace std;
    struct node{int fa,len;map<int,int> ch;}t[mxn*4];
    int poi,lt,rt,n;ll ans;
    void insert(int c)
    {
        int p=lt,np=lt=++poi; t[np].len=t[p].len+1;
        for(;p&&!t[p].ch[c];p=t[p].fa)	t[p].ch[c]=np;
        ans+=t[np].len;
    	if(!p){t[np].fa=rt;return;}
        int q=t[p].ch[c];
        if(t[q].len==t[p].len+1){ans-=t[q].len;t[np].fa=q;return;}
        int nq=++poi; t[nq].len=t[p].len+1;
        t[nq].ch=t[q].ch; ans-=t[nq].len;
        t[nq].fa=t[q].fa; t[q].fa=t[np].fa=nq;
        for(;p&&t[p].ch[c]==q;p=t[p].fa) t[p].ch[c]=nq;
    }
    int main()
    {
    	int x;
    	scanf("%d",&n);
    	lt=rt=++poi;
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d",&x);
    		insert(x);
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    

    本题还有一个非常优秀的做法就是SA

    我们发现 要求本质不同的前缀数量 那么就是 len - max_lcp 我们发现 这个不就是SA的height吗!

    我们可以通过倒过来删除的操作 链表维护一通 也是可以AC的~

    时间复杂度是O(nlgn) 瓶颈在于求SA 如果你是大佬写DC3的话请无视

    我这辈子也不可能写DC3的[Flag]

  • 相关阅读:
    linux批量远程多服务器FTP并下载文件的脚本
    NPM更换国内源
    Win10禁用无用的服务
    JS测试
    FastAdmin导出
    VScode全局设置
    Vue路由history模式
    kill_devtmpfsi
    获取域名URL
    Axios去除Respones中的config、headers、request
  • 原文地址:https://www.cnblogs.com/hanyuweining/p/10321915.html
Copyright © 2011-2022 走看看