惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Blog — PlanetScale
Blog — PlanetScale
小众软件
小众软件
F
Fortinet All Blogs
博客园 - 叶小钗
博客园_首页
D
DataBreaches.Net
Apple Machine Learning Research
Apple Machine Learning Research
U
Unit 42
爱范儿
爱范儿
aimingoo的专栏
aimingoo的专栏
博客园 - Franky
Martin Fowler
Martin Fowler
酷 壳 – CoolShell
酷 壳 – CoolShell
The Cloudflare Blog
A
About on SuperTechFans
Google DeepMind News
Google DeepMind News
Microsoft Security Blog
Microsoft Security Blog
IT之家
IT之家
M
MIT News - Artificial intelligence
有赞技术团队
有赞技术团队
博客园 - 【当耐特】
S
SegmentFault 最新的问题
Hugging Face - Blog
Hugging Face - Blog

博客园 - headchen

博文阅读密码验证 - 博客园 二进制集合运算 - headchen - 博客园 OI中字符串读入和处理 完全二叉树的性质 扫描线算法 评论备份(3) 评论备份(2) 用户中心 - 博客园 二分法的注意事项 二分图相关 KMP算法详解 用户中心 - 博客园 中国国家集训队论文集目录(1999-2009) 最短路Dijkstra算法的一些扩展问题 用户中心 - 博客园 async await 异步编程杂记 IOS 杂记 合并 ios 静态库 android studio 偶记
sam模板
headchen · 2018-03-30 · via 博客园 - headchen

SAM模板 

struct SAM{
    static const int maxn =  300010 * 2;
    struct node{
        node*nxt[26],*fail;
        int len;
    };
    
    node*root;int cnt;
    node no[maxn];
    node*newnode(){
        return &no[cnt++];
    }
    SAM(){
        cnt = 0;
        root = newnode();
    }
    
    node* add(node*p,int c){
        node*cur = newnode();
        cur->len = p->len+1;
        while(p &&!p->nxt[c])p->nxt[c] = cur,p = p->fail;
        if(!p){
            cur->fail = root;return cur;
        }
        node*q = p->nxt[c];
        if(q->len == p->len+1){
            cur->fail = q;
        }else{
            node*nq = newnode();
            *nq = *q;
            nq->len = p->len+1;
            q->fail = cur->fail = nq;
            while(p&&p->nxt[c]==q)p->nxt[c] = nq,p = p->fail;
        }
        return cur;
    }

    ll getNumOfDistinctSubstrings(){
        auto ans = 0;
        REP(i,1,cnt)ans+=no[i].len-no[i].fail->len;
        return (ans);
    }
};