列表

详情


NC213942. 仓鼠与点名

描述

输入描述

输入描述见上

输出描述

输出描述见上

示例1

输入:

1
6 3
cabcca
1 2 2 3 5
2
4
5

输出:

6
1
4

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++11) 解法, 执行用时: 893ms, 内存消耗: 212976K, 提交时间: 2020-11-23 19:19:23

#include <bits/stdc++.h>
#define inc(l,i,r) for (int i=l;i<=r;i++)
#define dec(r,i,l) for (int i=r;i>=l;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;

const int N = 400400;

struct state {int nxt[26], pre, len;} st[N*2];
int sz;

inline int extend(int last,int c) {
	int p = last, now = ++sz;
	st[now].len = st[last].len + 1;
	for (;~p && !st[p].nxt[c];p=st[p].pre) st[p].nxt[c] = now;
	if (p == -1) st[now].pre = 0;  else {
		int q = st[p].nxt[c];
		if (st[q].len == st[p].len+1) st[now].pre = q;  else {
			int clone = ++sz;
			st[clone] = st[q];  st[clone].len = st[p].len + 1;
			for (;~p && st[p].nxt[c] == q;p=st[p].pre) st[p].nxt[c] = clone;
			st[now].pre = st[q].pre= clone;
		}
	} return now;
}

int nxt[N][26], chr[N], f[N][20], pos[N];

inline int F(int x,int len) {
	dec(19,i,0) if (len >> i & 1) {
		x = f[x][i];
	}
	return x;
}

int Len;
bool cmp(int x,int y) {
	//printf("Len = %d cmp %d %d = %d\n",Len,x,y,chr[F(pos[x],Len)] < chr[F(pos[y],Len)]);
	return chr[F(pos[x],Len)] < chr[F(pos[y],Len)];
}

inline void build() {
	queue<pii> Q;
	Q.push(mp(0,0));
	while (!Q.empty()) {
		pii u = Q.front();  Q.pop();
		pos[u.se] = u.fi;
		inc(0,i,25) if (nxt[u.fi][i]) {
			int now = nxt[u.fi][i];
			Q.push(mp(now,extend(u.se,i)));
			chr[now] = i;
			f[now][0] = u.fi;
			inc(1,j,19) f[now][j] = f[f[now][j-1]][j-1];
		}
	}
}

int T, n, q, a[N], fa[N];
char s[N];
bool flag[N*2];
vector<int> belong[N*2], G[N*2], result;

int getfa(int x) {return (fa[x] == x) ? x : fa[x] = getfa(fa[x]);}

void dfs0(int u) {
	for (int v : G[u]) dfs0(v);
	if (u && pos[st[u].pre] == 0) {
		flag[st[u].pre] = true;
		pos[st[u].pre] = pos[u];
	}
}

void dfs(int u) {
	if (!flag[u]) {
		vector<int> &tmp = belong[pos[u]];
		for (int x : tmp) result.pb(x);
	}
	for (int v : G[u]) dfs(v);
}

int main() {
	//freopen("_in.txt","r",stdin);
	scanf("%d",&T);
	while (T--) {
		memset(st,0,sizeof(st));
		memset(nxt,0,sizeof(nxt));
		memset(chr,0,sizeof(chr));
		memset(f,0,sizeof(f));
		memset(pos,0,sizeof(pos));
		memset(flag,0,sizeof(flag));
		st[0].pre = -1;
		sz = 0;
		scanf("%d%d",&n,&q);
		
		result.clear();
		inc(0,i,n) {
			fa[i] = i;
			belong[i].clear();
		}
		scanf("%s",s+1);
		a[1] = 0;
		inc(2,i,n) scanf("%d",a+i);
		inc(1,i,n) {
			if (nxt[getfa(a[i])][s[i]-'a'])	{
				fa[i] = getfa(nxt[getfa(a[i])][s[i]-'a']);
			} else {
				nxt[getfa(a[i])][s[i]-'a'] = i;
			}
		}
		inc(1,i,n) belong[getfa(i)].pb(i);
		build();
		
		inc(1,i,sz) G[st[i].pre].pb(i);
		dfs0(0);

		inc(0,i,sz) {
			Len = st[i].len;
			sort(G[i].begin(),G[i].end(),cmp);
			// printf("%d | ",i);
			// for (int x : G[i]) printf("%d ",x);
			// putchar('\n');
		}
		dfs(0);
		// for (int i=0;i<(int)result.size();i++) printf("%d ",result[i]);
		// putchar(10);
		
		while (q--) {
			int k;
			scanf("%d",&k);
			printf("%d\n",result[k-1]);
		}
		inc(0,i,sz) {
			G[i].clear();
		}
	}
}

上一题