• BZOJ 4516. [Sdoi2016]生成魔咒【SAM 动态维护不同子串数量】


    [Sdoi2016]生成魔咒

    动态维护不同子串的数量
    想想如果只要查询一次要怎么做,那就是计算各个点的(len[u]-len[link[u]])然后求和即可,现在要求动态更新,我们可以保存一个答案,然后每次更新后缀链接的时候,如果是连接的话就要加上(len[u]-len[link[u]]),断开的话就要减去(len[u]-len[link[u]]),每次输出答案即可

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    #include<string>
    #include<algorithm>
    #include<stack>
    using namespace std;
    void ____(){ ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); }
    const int MAXN = 2e5+7;
    using LL = int_fast64_t;
    
    struct SAM{
        int len[MAXN],link[MAXN],tot,last;
        LL ret = 0;
        map<int,int> ch[MAXN];
        SAM(){ link[0] = -1; }
        void extend(int x){
            int np = ++tot, p = last;
            len[np] = len[p] + 1;
            while(p!=-1 and !ch[p].count(x)){
                ch[p].insert(make_pair(x,np));
                p = link[p];
            }
            if(p==-1) link[np] = 0;
            else{
                int q = ch[p][x];
                if(len[p]+1==len[q]) link[np] = q;
                else{
                    int clone = ++tot;
                    len[clone] = len[p] + 1;
                    link[clone] = link[q];
                    ret += len[clone] - len[link[clone]];
                    ch[clone] = ch[q];
                    ret -= len[q] - len[link[q]];
                    link[q] = link[np] = clone;
                    ret += len[q] - len[clone];
                    while(p!=-1 and ch[p].count(x) and ch[p].at(x)==q){
                        ch[p].at(x) = clone;
                        p = link[p];
                    }
                }
            }   
            last = np;
            ret += len[np] - len[link[np]];
        }
    }sam;
    int n;
    int main(){
        scanf("%d",&n);
        for(int i = 1; i <= n; i++){
            int x; scanf("%d",&x);
            sam.extend(x);
            printf("%lld
    ",sam.ret);
        }
        return 0;
    }
    
  • 相关阅读:
    hdu 2492 树状数组 Ping pong
    HDU 1532 基础EK Drainage Ditches
    EK算法模板
    Codeforces Round #538 (Div. 2) (A-E题解)
    Codeforces Global Round 1 (A-E题解)
    Educational Codeforces Round 59 (Rated for Div. 2) DE题解
    Codeforces Round #535 (Div. 3) 题解
    Codeforces Round #534 (Div. 2) D. Game with modulo(取余性质+二分)
    POJ2253:Frogger(改造Dijkstra)
    POJ1797:Heavy Transportation(改造Dijkstra)
  • 原文地址:https://www.cnblogs.com/kikokiko/p/12706116.html
Copyright © 2020-2023  润新知