[Solution]
It is likely that you need to modify the dfs order by a dynamic data structure. However, n is not big enough to use log-level algorithm. Divide the tree into sqrt(n) parts. Then use treaps to modify each part.
[Code]
So ugly and slow.
#include <cstdio>
#include <cctype>
#include <cstdlib>
#include <algorithm>
using namespace std;
struct edge {
int t;
edge *next;
};
template <class _INT>
void readInt(_INT& s) {
int d;
bool nag = 0;
s = 0;
while (!isdigit(d = getchar()))
if (d == '-')
nag = 1;
while ((s = s * 10 + d - 48), isdigit(d = getchar()));
if (nag)
s = -s;
}
const int maxn = 60009;
int n, m, lans, fa[maxn], w[maxn], d[maxn];
int pcsz, tp, fp[maxn], pd0[maxn], prt[maxn], pfa[maxn];
edge *ht[maxn], *hp[maxn], *ep, elst[maxn * 6];
namespace treap {//{{{
int tn, ls[maxn], rs[maxn], vl[maxn], w[maxn], sz[maxn];
inline void init() {
tn = 0;
sz[0] = 0;
}
inline int newNode(int v) {
++ tn;
ls[tn] = 0;
rs[tn] = 0;
vl[tn] = v;
sz[tn] = 1;
w[tn] = rand();
return tn;
}
inline void lRot(int& p) {
int q = rs[p];
rs[p] = ls[q];
ls[q] = p;
sz[q] = sz[p];
sz[p] = sz[ls[p]] + sz[rs[p]] + 1;
p = q;
}
inline void rRot(int& p) {
int q = ls[p];
ls[p] = rs[q];
rs[q] = p;
sz[q] = sz[p];
sz[p] = sz[ls[p]] + sz[rs[p]] + 1;
p = q;
}
inline void maintain(int& p, bool d) {
if (d) {
if (w[ls[p]] > w[p])
rRot(p);
}
else
if (w[rs[p]] > w[p])
lRot(p);
}
void ins(int& p, int v) {
if (!p)
p = newNode(v);
else {
if (v < vl[p])
ins(ls[p], v);
else
ins(rs[p], v);
++ sz[p];
maintain(p, v < vl[p]);
}
}
bool ers(int& p, int v) {
if (!p)
return 0;
else if (vl[p] == v) {
if (!ls[p])
p = rs[p];
else if (!rs[p])
p = ls[p];
else {
int q = ls[p];
while (rs[q])
q = rs[q];
vl[p] = vl[q];
-- sz[p];
return ers(ls[p], vl[p]);
}
return 1;
}
else {
-- sz[p];
if (v < vl[p])
return ers(ls[p], v);
else
return ers(rs[p], v);
}
}
int cntUpper(int p, int v) {
if (!p)
return 0;
else if (vl[p] > v)
return sz[rs[p]] + 1 + cntUpper(ls[p], v);
else
return cntUpper(rs[p], v);
}
};//}}}
inline void addEdge(edge** head, int u, int v) {
ep-> t = v;
ep-> next = head[u];
head[u] = ep ++;
}
void buildTree() {
static int q[maxn];
int hd = 0, tl = 1;
for (int i = 0; i < maxn; ++ i)
fa[i] = -1;
q[hd] = 1;
fa[1] = 0;
d[1] = 1;
fp[0] = 0;
tp = 0;
while (hd < tl) {
int p = q[hd ++];
if (fa[p] && d[p] - pd0[fp[fa[p]]] < pcsz) {
fp[p] = fp[fa[p]];
treap :: ins(prt[fp[p]], w[p]);
}
else {
fp[p] = ++ tp;
treap :: ins(prt[fp[p]], w[p]);
pd0[fp[p]] = d[p];
pfa[fp[p]] = fp[fa[p]];
addEdge(hp, fp[fa[p]], fp[p]);
}
for (edge* e = ht[p]; e; e = e-> next)
if (fa[e-> t] == -1) {
fa[e-> t] = p;
d[e-> t] = d[p] + 1;
q[tl ++] = e-> t;
}
}
}
int query(int p, int v) {
static int q[maxn], qp[maxn];
int hd = 0, tl = 1, tq = 0, s = 0, p0 = fp[p];
q[hd] = p;
while (hd < tl) {
int p = q[hd ++];
if (w[p] > v)
s ++;
for (edge* e = ht[p]; e; e = e-> next)
if (fa[e-> t] == p) {
if (fp[e-> t] == fp[p])
q[tl ++] = e-> t;
else
qp[tq ++] = fp[e-> t];
}
}
hd = 0, tl = tq;
while (hd < tl) {
int p = qp[hd ++];
if (p != p0)
s += treap :: cntUpper(prt[p], v);
for (edge* e = hp[p]; e; e = e-> next)
if (pfa[e-> t] == p)
qp[tl ++] = e-> t;
}
return s;
}
int main() {
srand(45239423);
treap :: init();
for (int i = 0; i < maxn; ++ i)
prt[i] = 0;
ep = elst;
readInt(n);
for (pcsz = 0; pcsz * pcsz < n * 2; ++ pcsz);
lans = 0;
for (int i = 0; i < n - 1; i ++) {
int u, v;
readInt(u);
readInt(v);
addEdge(ht, u, v);
addEdge(ht, v, u);
}
for (int i = 1; i <= n; i ++)
readInt(w[i]);
buildTree();
readInt(m);
while (m --) {
int opt, u, x;
readInt(opt);
readInt(u);
readInt(x);
u ^= lans;
x ^= lans;
if (u > n) {
for (int i = 0; i < m; ++ i)
puts("WAAAAAAAAAA");
return 12345;
}
if (opt == 0)
printf("%d\n", (lans = query(u, x)));
else if (opt == 1) {
treap :: ers(prt[fp[u]], w[u]);
w[u] = x;
treap :: ins(prt[fp[u]], w[u]);
}
else if (opt == 2) {
n ++;
addEdge(ht, u, n);
fa[n] = u;
w[n] = x;
int p = n;
d[p] = d[fa[p]] + 1;
if (d[p] - pd0[fp[fa[p]]] < pcsz) {
fp[p] = fp[fa[p]];
treap :: ins(prt[fp[p]], w[p]);
}
else {
fp[p] = ++ tp;
treap :: ins(prt[fp[p]], w[p]);
pd0[fp[p]] = d[p];
pfa[fp[p]] = fp[fa[p]];
addEdge(hp, fp[fa[p]], fp[p]);
}
}
lans = 0;
}
}