zoukankan      html  css  js  c++  java
  • BZOJ 4516: [Sdoi2016]生成魔咒 [后缀自动机]

    4516: [Sdoi2016]生成魔咒

    题意:询问一个字符串每个前缀有多少不同的子串


    做了一下SDOI2016R1D2,题好水啊随便AK

    强行开map上SAM
    每个状态的贡献就是(Max(s)-Min(s)+1)
    插入的时候维护一下就行了

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <map>
    using namespace std;
    typedef long long ll;
    #define fir first
    #define sec second
    const int N=3e5+5, P=1e9+7;
    inline int read() {
    	char c=getchar(); int x=0, f=1;
    	while(c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
    	while(c>='0' && c<='9') {x=x*10+c-'0'; c=getchar();}
    	return x*f;
    }
    
    int n, s[N]; ll ans;
    struct meow { map<int, int> ch; int par, val;}t[N];
    int sz=1, root=1, last=1;
    void extend(int c) {
    	int p=last, np=++sz;
    	t[np].val = t[p].val+1;
    	for(; p && !t[p].ch[c]; p=t[p].par) t[p].ch[c]=np;
    	if(!p) t[np].par = root;
    	else {
    		int q=t[p].ch[c];
    		if(t[q].val == t[p].val+1) t[np].par=q;
    		else {
    			ans -= t[q].val - t[p].val;
    			int nq=++sz; t[nq]=t[q]; t[nq].val = t[p].val+1;
    			t[q].par = t[np].par = nq;
    			ans += t[q].val - t[nq].val; ans ++;
    			for(; p && t[p].ch[c]==q; p=t[p].par) t[p].ch[c] = nq;
    		}
    	}
    	ans+=t[np].val - t[t[np].par].val;
    	last=np;
    }
    int main() {
    	//freopen("in","r",stdin);
    	freopen("incantation.in","r",stdin);
    	freopen("incantation.out","w",stdout);
    	n=read();
    	for(int i=1; i<=n; i++) {
    		s[i]=read();
    		extend(s[i]);
    		printf("%lld
    ",ans);
    	}
    }
    
    
  • 相关阅读:
    luogu P2685 [USACO07OPEN]抓牛Catch That Cow
    codevs 2021 中庸之道
    1018. 锤子剪刀布 (20)
    1017. A除以B (20)
    1016. 部分A+B (15)
    1013. 数素数 (20)
    1011. A+B和C (15)
    《C语言程序设计(第四版)》阅读心得(三)
    《C语言程序设计(第四版)》阅读心得(二)
    1008. 数组元素循环右移问题 (20)
  • 原文地址:https://www.cnblogs.com/candy99/p/6652757.html
Copyright © 2011-2022 走看看