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;
    }
    

      

  • 相关阅读:
    html转义
    mongodb 数据库 基础使用
    xpath基本语法
    HTTP
    JavaScript笔记6-数组新方法
    JavaScript笔记5-事件
    JavaScript笔记3--标识符和保留字
    JavaScript笔记4-数组
    jquery笔记1--选择器
    JavaScript笔记2
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/5954259.html
Copyright © 2011-2022 走看看