3720: Gty的妹子树
思路:块状树
代码:
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define y1 y11
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pli pair<LL, int>
#define pii pair<int, int>
#define piii pair<pii, int>
#define pdd pair<double, double>
#define mem(a, b) memset(a, b, sizeof(a))
#define debug(x) cerr << #x << " = " << x << "
";
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//head
const int N = 6e4 + 10;
vector<int> g[N], G[N];
int blo, n, m, op, u, v, x, w[N], bl[N], fa[N], cnt;
struct Block {
vector<int> b;
inline void ins(int x) {
b.pb(w[x]);
int sz = b.size();
for (int i = sz-2; i >= 0; --i) {
if(b[i] > b[i+1]) swap(b[i], b[i+1]);
else break;
}
}
inline void upd(int u, int x) {
int p = lower_bound(b.begin(), b.end(), w[u]) - b.begin();
b[p] = x;
w[u] = x;
for (int i = p-1; i >= 0; --i) {
if(b[i] > b[i+1]) swap(b[i], b[i+1]);
else break;
}
for (int i = p; i+1 < b.size(); ++i) {
if(b[i] > b[i+1]) swap(b[i], b[i+1]);
else break;
}
}
inline int query(int x) {
return (b.end()-upper_bound(b.begin(), b.end(), x));
}
}block[N];
void dfs(int u, int o, int x) {
block[x].ins(u);
bl[u] = x;
fa[u] = o;
for (int i = 0; i < g[u].size(); ++i) {
int v = g[u][i];
if(v == o) continue;
if(block[x].b.size() == blo) {
++cnt;
G[x].pb(cnt);
dfs(v, u, cnt);
}
else dfs(v, u, x);
}
}
inline int dfs1(int u, int x) {
int ans = block[u].query(x);
for (int i = 0; i < G[u].size(); ++i) {
int v = G[u][i];
ans +=dfs1(v, x);
}
return ans;
}
inline int dfs0(int u, int x) {
int ans = 0;
if(w[u] > x) ans++;
for (int i = 0;i < g[u].size(); ++i) {
int v = g[u][i];
if(v == fa[u]) continue;
if(bl[v] == bl[u]) ans += dfs0(v, x);
else ans += dfs1(bl[v], x);
}
return ans;
}
int main() {
int lastans = 0;
scanf("%d", &n);
blo = sqrt(2*n*log2(n)+0.5);
for (int i = 1; i < n; ++i) scanf("%d %d", &u, &v), g[u].pb(v), g[v].pb(u);
for (int i = 1; i <= n; ++i) scanf("%d", &w[i]);
dfs(1, 0, 0);
scanf("%d", &m);
while(m--) {
scanf("%d %d %d", &op, &u, &x);
u ^= lastans;
x ^= lastans;
if(op == 0) {
lastans = dfs0(u, x);
printf("%d
", lastans);
}
else if(op == 1){
block[bl[u]].upd(u, x);
}
else {
++n;
w[n] = x;
fa[n] = u;
g[u].pb(n);
if(block[bl[u]].b.size() == blo) {
++cnt;
G[bl[u]].pb(cnt);
bl[n] = cnt;
block[bl[n]].ins(n);
}
else {
bl[n] = bl[u];
block[bl[n]].ins(n);
}
}
}
return 0;
}