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

    Description

    给出一串数字,求每次插入一个数字后本质不同的子串.

    Sol

    SAM.

    在 SAM 上添加节点的时候统计一下 (val[np]-val[par[np]]) 就可以了...

    用 map 存一下边,复杂度 (O(nlogn))

    Code

    /**************************************************************
        Problem: 4516
        User: BeiYu
        Language: C++
        Result: Accepted
        Time:812 ms
        Memory:14940 kb
    ****************************************************************/
     
    #include<cstdio>
    #include<cstring>
    #include<map>
    #include<iostream>
    using namespace std;
     
    typedef long long LL;
    const int N = 200005;
     
    int n,cnt,rt,lst;
    LL ans;
    map<int,int> go[N];
    int par[N],val[N];
     
    inline int in(int x=0,char ch=getchar()){ while(ch>'9'||ch<'0') ch=getchar();
        while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; }
     
    void Extend(int w=in()){
        int p=lst,np=++cnt;
        val[np]=val[p]+1;
        while(p && go[p][w]==0) go[p][w]=np,p=par[p];
        if(!p) par[np]=rt;
        else{
            int q=go[p][w];
            if(val[p]+1 == val[q]) par[np]=q;
            else{
                int nq=++cnt;
                val[nq]=val[p]+1,go[nq]=go[q],par[nq]=par[q];
                par[q]=par[np]=nq;
                while(p && go[p][w]==q) go[p][w]=nq,p=par[p];
            }
        }ans+=val[np]-val[par[np]],lst=np;
    }
     
    int main(){
        lst=rt=++cnt,n=in();
        for(int i=1;i<=n;i++) Extend(),printf("%lld
    ",ans);
        return 0;
    }
    

      

  • 相关阅读:
    第十六天-面向对象02-成员
    第十五天-面向对象01
    第十四天-内置函数
    第十三天-生成器
    第十二天-函数名 迭代器
    第十一天-函数进阶
    第十天-初识函数
    第九天- 文件操作 r w a 文件复制/修改
    objectives-c基本语法。
    今天开始了objective-c的学习!
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/5954259.html
Copyright © 2011-2022 走看看