# 七彩树

### Description

，为了方便起见，你可以认为树上相邻的两个点之间的距离为1。站在这棵色彩斑斓的树前面，你将面临m个问题。

。请写一个程序，快速回答这些询问。

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

### Sample Output

1
2
3
1
1
2
1
1


#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
struct lpl{
int fa, dfn, top, son, size, deep;
}a[maxn];
struct ld{
int id, dfn;
inline bool operator < (const ld &A)const{return dfn < A.dfn;}
};
struct lpd{
int sum, ls, rs;
}node[10000010];
int n, m, c[maxn];
int lastans, last, num, tot, opt, cnt, mxd, root = 1;
int d[maxn], rt[maxn * 5], ot[maxn], dp[maxn];
vector<int> point[maxn];
set<ld> s[maxn];
set<ld>::iterator iter, op, ed;
queue<int> q;

namespace HLD{
void dfs1(int t, int fa){
a[t].size = 1; int tmp = 0; mxd = max(mxd, a[t].deep);
for(int i = point[t].size() - 1; i >= 0; --i){
int now = point[t][i]; if(now == fa) continue;
a[now].deep = a[t].deep + 1; dfs1(now, t);
a[t].size += a[now].size;
if(tmp < a[now].size){tmp = a[now].size; a[t].son = now;}
}
}

void dfs2(int t, int fa){
a[t].dfn = ++num;
if(a[t].son){a[a[t].son].top = a[t].top; dfs2(a[t].son, t);}
for(int i = point[t].size() - 1; i >= 0; --i){
int now = point[t][i]; if(now == fa || now == a[t].son) continue;
a[now].top = now; dfs2(now, t);
}
}

inline int LCA(int x1, int x2){
if(a[a[x1].top].deep < a[a[x2].top].deep) swap(x1, x2);
while(a[x1].top != a[x2].top){
x1 = a[a[x1].top].fa;
if(a[a[x1].top].deep < a[a[x2].top].deep) swap(x1, x2);
}
return (a[x1].deep > a[x2].deep) ? x2 : x1;
}
}

namespace SGT{
inline void update(int t){node[t].sum = node[node[t].ls].sum + node[node[t].rs].sum;}

void build(int &t, int l, int r){
t = ++cnt; node[t].sum = 0; if(l == r) return;
int mid = (l + r) >> 1;
build(node[t].ls, l, mid); build(node[t].rs, mid + 1, r);
}

void Modify(int &t, int l, int r, int pos, int val){
t = ++cnt; node[t] = node[last];
if(l == r){node[t].sum += val; return;}
int mid = (l + r) >> 1;
if(pos <= mid){last = node[last].ls; Modify(node[t].ls, l, mid, pos, val);}
else{last = node[last].rs; Modify(node[t].rs, mid + 1, r, pos, val);}
update(t);
}

int Query(int t, int l, int r, int ql, int qr){
if(l == ql && r == qr) return node[t].sum;
int mid = (l + r) >> 1;
if(qr <= mid) return Query(node[t].ls, l, mid, ql, qr);
if(mid < ql) return Query(node[t].rs, mid + 1, r, ql, qr);
return Query(node[t].ls, l, mid, ql, mid) + Query(node[t].rs, mid + 1, r, mid + 1, qr);
}
}

template<typename T>
x = 0; static char c = getchar();
while(!isdigit(c)) c = getchar();
while(isdigit(c)){x = x * 10 + c - '0'; c = getchar();}
}

template<typename T>
void write(T x){
if(x / 10) write(x / 10);
putchar(x % 10 + '0');
}

inline void putit(){
for(int i = 1; i <= n; ++i) {
point[i].clear(); s[i].clear();
}
for(int f, i = 1; i < n; ++i){
read(f); a[i + 1].fa = f;
point[f].push_back(i + 1);
}
}

inline void prepare(){
a[root].deep = 1; num = 0; memset(rt, 0, sizeof(rt));
HLD::dfs1(root, 0); a[1].top = 1; HLD::dfs2(root, 0);
q.push(root); int now; tot = 0;
while(!q.empty()){
now = q.front(); q.pop(); d[++tot] = now;
for(int i = point[now].size() - 1; i >= 0; --i) q.push(point[now][i]);
}
cnt = 0; SGT::build(rt[0], 1, n); opt = 0;
bool qian, hou;
for(int color, i = 1; i <= tot; ++i){
color = c[d[i]];
iter = s[color].insert((ld){d[i], a[d[i]].dfn}).first;
qian = (iter != s[color].begin()); iter++; hou = (iter != s[color].end()); iter--;
if(qian){iter--; op = iter; iter++;}
if(hou){iter++; ed = iter; iter--;}
if(qian && hou){
last = rt[opt];
SGT::Modify(rt[++opt], 1, n, a[HLD::LCA(op -> id, ed -> id)].dfn, 1);
}
if(qian){
last = rt[opt];
SGT::Modify(rt[++opt], 1, n, a[HLD::LCA(op -> id, iter -> id)].dfn, -1);
}
if(hou){
last = rt[opt];
SGT::Modify(rt[++opt], 1, n, a[HLD::LCA(iter -> id, ed -> id)].dfn, -1);
}
last = rt[opt]; SGT::Modify(rt[++opt], 1, n, iter -> dfn, 1);
ot[d[i]] = opt; dp[a[d[i]].deep] = d[i];
}
}

inline void workk(){
int x, D;
while(m--){
x ^= lastans; D ^= lastans;
D += a[x].deep; D = min(D, mxd);
D = ot[dp[D]];
lastans = SGT::Query(rt[D], 1, n, a[x].dfn, a[x].dfn + a[x].size - 1);
write(lastans); putchar(10);
}
}

int main()
{