fastle
垆边人似月 皓腕凝霜雪
/*
线段树合并 维护每个颜色的最小深度即可
??? 要强制在线

考虑不限制深度的方法统计子树中的颜色个数将每种颜色按照dfs序排序,  然后树上每个点答案贡献 + 1, 同种颜色相邻dfs序的lca处-1
这样统计子树和即可

考虑假如有深度限制的话, 这个方法可以离线来做, 按照深度从小到大一层一层地加入点, 同时对于每种
颜色按照dfs序维护set, 那么对于所有的询问按照deep[x] + d排序就可以处理了

现在要求在线, 那么按照深度建立主席树, 每次在上面查询就好了

l 写成1 debug3小时 

*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#include<cmath>
#include<set>
#define ll long long
#define M 200010
#define mmp make_pair
using namespace std;
int read() {
	int nm = 0, f = 1;
	char c = getchar();
	for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
	for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
	return nm * f;
}
int n, m, t, deep[M], root[M], sz[M], son[M], fa[M], top[M], dfn[M], low[M], dft, cor[M], maxdeep, ans, cnt;
vector<int> to[M], note[M];

struct cmp {
	bool operator () (const int &a, const int &b) const {
		return dfn[a] < dfn[b];
	}
};
set<int, cmp> st[M];
set<int>::iterator it, it2;
void init() {
	for(int i = 1; i <= n; i++) vector<int>().swap(to[i]), vector<int>().swap(note[i]), st[i].clear(), son[i] = 0;
	maxdeep = ans = cnt = dft = 0;
}

void dfs(int now, int f) {
	deep[now] = deep[f] + 1;
//	note[deep[now]].push_back(now);
	maxdeep = max(maxdeep, deep[now]);
	sz[now] = 1;
	for(int i = 0; i < to[now].size(); i++) {
		int vj = to[now][i];
		dfs(vj, now);
		if(sz[vj] > sz[son[now]]) son[now] = vj;
		sz[now] += sz[vj];
	}
}

void dfs(int now) {
	dfn[now] = ++dft;
	note[deep[now]].push_back(now);/*
	if(son[now]) {
		top[son[now]] = top[now];
		dfs(son[now]);
	}*/
	for(int i = to[now].size() - 1; i >= 0; i--) {
		int vj = to[now][i];
		if(vj == son[now]) top[vj] = top[now];
		else top[vj] = vj;
		dfs(vj);
	}
	low[now] = dft;
}

int lca(int a, int b) {
	while(top[a] != top[b]) {
		if(deep[top[a]] < deep[top[b]]) swap(a, b);
		a = fa[top[a]];
	}
	if(deep[a] > deep[b]) swap(a, b);
	return a;
}

int rt[M], ls[M * 50], rs[M * 50], v[M * 50];

void insert(int l, int r, int &now, int pos, int val) {
	if(!now) {
		now = ++cnt;
		ls[now] = rs[now] = v[now] = 0;
	}
	if(l == r) {
		v[now] += val;
		return;
	}
	int mid = (l + r) >> 1;
	if(pos <= mid) insert(l, mid, ls[now], pos, val);
	else insert(mid + 1, r, rs[now], pos, val);
	v[now] = v[ls[now]] + v[rs[now]];
}

int merge(int last, int now, int l, int r) {
	if(!last || !now) return last + now;
	if(l == r) {
		v[now] += v[last];
		return now;
	}
	int mid = (l + r) >> 1;
	ls[now] = merge(ls[last], ls[now], l, mid);
	rs[now] = merge(rs[last], rs[now], mid + 1, r);
	v[now] = v[ls[now]] + v[rs[now]];
	return now;
}

int query(int l, int r, int now, int ln, int rn) {
	if(l > rn || r < ln) return 0;
	if(l >= ln && r <= rn) return v[now]; 
	int mid = (l + r) >> 1;
	return query(l, mid, ls[now], ln, rn) + query(mid + 1, r, rs[now], ln, rn);
}

int main() {
//	freopen("1.in", "r", stdin);	freopen("2.out", "w", stdout);
	t = read();
	while(t--) {
		n = read(), m = read();
		init();
		for(int i = 1; i <= n; i++) cor[i] = read();
		for(int i = 2; i <= n; i++) fa[i] = read(), to[fa[i]].push_back(i);
		dfs(1, 0);
		top[1] = 1;
		dfs(1);
		rt[0] = 0;
		for(int d = 1; d <= maxdeep; d++) {
			rt[d] = 0;
			for(int i = note[d].size() - 1; i >= 0; i--) {
				int x = note[d][i];
				
			//	cout << x << " " << deep[x] << " " << dfn[x] << " " << cnt<< "\n";
				insert(1, n, rt[d], dfn[x], 1);
				it = st[cor[x]].lower_bound(x);
				int pre = -1, nxt = -1;
				if(it != st[cor[x]].end()) nxt = *it;
				if(it != st[cor[x]].begin()) pre = *(--it);
				if(pre != -1) insert(1, n, rt[d], dfn[lca(pre, x)], -1);
				if(nxt != -1) insert(1, n, rt[d], dfn[lca(x, nxt)], -1);
				if(pre != -1 && nxt != -1) insert(1, n, rt[d], dfn[lca(pre, nxt)], 1);
				st[cor[x]].insert(x);
			}
			rt[d] = merge(rt[d - 1], rt[d], 1, n);
		}
//		for(int i = 1; i < n; i++) cout << lca(i, i + 1) << " ";
	//	break;
		
		while(m--) {
			int x = read() ^ ans, d = read() ^ ans;
			d = min(maxdeep, deep[x] + d);
			ans = query(1, n, rt[d], dfn[x], low[x]);
			cout << ans << '\n';
		}
	}
	return 0;
}
/*
3
3 3
1 2 3
1 2
1 1 
2 2
3 3 
5 8
1 3 3 2 2
1 1 3 3
1 0
0 0
3 0
1 3
2 1
2 0
6 2
4 1

5 8
1 3 3 2 2
1 1 3 3
1 0
0 0
3 0
1 3
2 1
2 0
6 2
4 1
1
5 5
1 2 3 4 5
1 1 1 1
1 1 
1 1
0 0
1 1
5 5
*/


posted on 2019-03-12 17:49  fastle  阅读(131)  评论(0编辑  收藏  举报