【BZOJ 4516】【SDOI 2016】生成魔咒

http://www.lydsy.com/JudgeOnline/problem.php?id=4516
后缀自动机直接做。。。省选时cena评测竟然没有卡掉map
每次加一个字符,增加的子串数目为np的max减去np的值parent的max值。
时间复杂度\(O(nlogn)\)

#include<map>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int in() {
	int k = 0; char c = getchar();
	for(; c < '0' || c > '9'; c = getchar());
	for(; c >= '0' && c <= '9'; c = getchar())
		k = k * 10 + c - 48;
	return k;
}

struct State {
	State *par;
	map <int, State*> go;
	int val;
	State(int _val) : par(0), val(_val) {
		go.clear();
	}
} *root, *last;

ll ans;

void extend(int w) {
	State *p = last;
	State *np = new State(p->val + 1);
	while (p && p->go[w] == 0)
		p->go[w] = np, p = p->par;
	if (p == 0) np->par = root;
	else {
		State *q = p->go[w];
		if (q->val == p->val + 1) np->par = q;
		else {
			State *nq = new State(p->val + 1);
			nq->go = q->go;
			nq->par = q->par;
			q->par = np->par = nq;
			while (p && p->go[w] == q)
				p->go[w] = nq, p = p->par;
		}
	}
	ans += np->val - np->par->val; printf("%lld\n", ans);
	last = np;
}

int main() {
	int n;
	root = last = new State(0);
	n = in();
	
	for(int i = 1; i <= n; ++i)
		extend(in());
	
	return 0;
}
posted @ 2016-10-02 19:49  abclzr  阅读(213)  评论(0编辑  收藏  举报