bzoj 4516 生成魔咒

来源:互联网 发布:网络招聘司机 编辑:程序博客网 时间:2024/05/04 16:21

因为SAM增量法构造的特点,所以每一次增加节点计算就可以了

因为SAM的转移是线性的,所以开个map也是兹辞的

#include<bits/stdc++.h>using namespace std;const int maxn = 112345;struct Node{    int len,fa;    map<int,int> nex;    Node(int _len = 0){        len = _len;        fa = 0;        nex.clear();    }    void copy(const Node & v){        nex = v.nex;        fa = v.fa;    }    bool exist(int x){        return nex.find(x) != nex.end();    }}node[maxn*2]; int _cnt;int newNode(int len){    node[_cnt] = Node(len);    return _cnt++;}int root,omg;void init(){    _cnt = 1;    root = omg = newNode(0);}void extend(int x){    int ox = newNode(node[omg].len+1);    while(omg && !node[omg].exist(x)){        node[omg].nex[x] = ox;        omg = node[omg].fa;    }    if(!omg) node[ox].fa = root;    else{        int omgx = node[omg].nex[x];        if(node[omg].len + 1 == node[omgx].len) node[ox].fa = omgx;        else{            int ax = newNode(node[omg].len+1);            node[ax].copy(node[omgx]);            node[ox].fa = node[omgx].fa = ax;            while(omg && node[omg].exist(x) && node[omg].nex[x] == omgx){                node[omg].nex[x] = ax;                omg = node[omg].fa;            }        }    }    omg = ox;}#define LL long long int main(){    int n;    while(~scanf("%d",&n)){        LL ans = 0;        init();        int x;        while(n--){            scanf("%d",&x);            extend(x);            ans += node[omg].len - node[node[omg].fa].len;            printf("%lld\n",ans);        }    }    return 0;}
0 0
原创粉丝点击