记录编号 216466 评测结果 AAAAAAAAAA
题目名称 [SCOI 2012] 喵星球上的点名 最终得分 100
用户昵称 Gravatarassassain 是否通过 通过
代码语言 C++ 运行时间 0.674 s
提交时间 2015-12-29 09:55:52 内存使用 9.85 MiB
显示代码纯文本
#define MAXN 200010UL
#include <cstdio>
#include <map>
#include <vector>
#include <queue>

using namespace std;

int n, m, num, bg[500100], v[400010], ans[MAXN], lt[MAXN], rt[MAXN], mid[MAXN], c[400010], w[400010];

struct ME {
	ME *fl;
	map<int, ME*>op;
	vector<int>ch;
	int last_x, id, se;
}*Rt;

void Insert(ME *rt,int len,int k) {
	for(int i = 1 ; i <= len ; ++ i) {
		if(!rt->op[c[i]]) {
			rt->op[c[i]] = new ME();
			rt->op[c[i]]->id = ++ num;
			rt->ch.push_back(c[i]);
		}
		rt = rt->op[c[i]];
	}
	bg[k] = rt->id;
	++ rt->se;
	return;
}

void Get_fail() {
	queue<ME*>q;
	q.push(Rt);
	while(!q.empty()) {
		ME *tmp = q.front();
		q.pop();
		int len = tmp->ch.size();
		for(int i = 0 ; i < len ; ++ i) {
			ME *p = tmp->fl;
			int np = tmp->ch[i];
			while(p&&!p->op[np]) p = p->fl;
			if(!p) tmp->op[np]->fl = Rt;
			else tmp->op[np]->fl = p->op[np];
			q.push(tmp->op[np]);
		}
	}
	return;
}

void Work(ME *rt,int l,int r,int k) {
	for(int i = l ; i <= r ; ++ i) {
		if(rt->op[w[i]]) {
			rt = rt->op[w[i]];
		} else {
			ME *p = rt->fl;
			while(p&&!p->op[w[i]]) p = p->fl;
			if(!p) rt = Rt;
			else rt = p->op[w[i]];
		}
		ME *tmp = rt;
		while(tmp&&tmp->last_x!=k) {
			ans[k] += tmp->se;
			tmp->last_x = k;
			++ v[tmp->id];
			tmp = tmp->fl;
		}
	}
	return;
}

int main() {
	freopen("wtfname.in", "r", stdin);
	freopen("wtfname.out", "w", stdout);
	int x;
	Rt = new ME();
	scanf("%d%d", &n, &m);
	for(int i = 1 ; i <= n ; ++ i) {
		scanf("%d", &x);
		lt[i] = rt[i-1]+1;
		mid[i] = lt[i]+x-1;
		for(int j = 0 ; j < x ; ++ j) scanf("%d", &w[lt[i]+j]);
		scanf("%d", &x);
		rt[i] = mid[i]+x;
		for(int j = 1 ; j <= x ; ++ j) scanf("%d", &w[mid[i]+j]);
	}
	for(int i = 1 ; i <= m ; ++ i) {
		scanf("%d", &x);
		for(int j = 1 ; j <= x ; ++ j) scanf("%d", &c[j]);
		Insert(Rt, x, i);
	}
	Get_fail();
	for(int i = 1 ; i <= n ; ++ i) {
		Work(Rt, lt[i], mid[i], i);
		Work(Rt, mid[i]+1, rt[i], i);
	}
	for(int i = 1 ; i <= m ; ++ i) {
		printf("%d\n", v[bg[i]]);
	}
	if(n) printf("%d", ans[1]);
	for(int i = 2 ; i <= n ; ++ i) {
		printf(" %d", ans[i]);
	}
	return 0;
}