比赛 |
树形数据结构拔高 |
评测结果 |
AAAAAAAAAAAAAWWWWWWW |
题目名称 |
滑稽♂树 |
最终得分 |
65 |
用户昵称 |
flyfree |
运行时间 |
5.042 s |
代码语言 |
C++ |
内存使用 |
17.23 MiB |
提交时间 |
2025-04-17 21:28:13 |
显示代码纯文本
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pir pair<ll,ll>
#define ls first
#define rs second
#define mp make_pair
#define mod
#define MAXN 30010
#define qmod(x) (x>mod?x-mod:x)
inline ll read(){
ll x = 0,f = 1;
char c = getchar();
while(c < '0'||c > '9'){
if(c == '-')f = -1;
c = getchar();
}
while(c >= '0'&&c <= '9'){
x = x*10+c-'0';
c = getchar();
}
return x*f;
}
struct node_FHQtreep{
ll s[MAXN * 50][2],val[MAXN * 50],key[MAXN * 50],siz[MAXN * 50];
ll idx;
ll newnode(ll x){
++ idx;
s[idx][1] = s[idx][0] = 0;
val[idx] = x;
key[idx] = rand();
siz[idx] = 1;
return idx;
}
void update(ll now){
siz[now] = siz[s[now][0]] + siz[s[now][1]] + 1;
}
void split_val(ll &x, ll &y, ll v, ll p){
if(!p){
x = y = 0;
return;
}
if(val[p] <= v){
x = p;
split_val(s[p][1], y, v, s[p][1]);
}else{
y = p;
split_val(x, s[p][0], v, s[p][0]);
}
update(p);
}
void split_siz(ll &x, ll &y, ll v, ll p){
if(!p){
x = y = 0;
return;
}
if(siz[s[p][0]] < v){
x = p;
split_siz(s[p][1], y, v - siz[s[p][0]] - 1, s[p][1]);
}else{
y = p;
split_siz(x, s[p][0], v, s[p][0]);
}
}
ll merge(ll x, ll y){
if(!x || !y){
return x | y;
}
if(key[x] >= key[y]){
s[x][1] = merge(s[x][1], y);
update(x);
return x;
}else{
s[y][0] = merge(x, s[y][0]);
update(y);
return y;
}
}
void del(ll v, ll &rot){
ll x,y,z;
split_val(x, y, v - 1, rot);
split_siz(y, z, 1, y);
rot = merge(x, z);
}
void insert(ll v, ll &rot){
ll x,y,z = newnode(v);
split_val(x, y, v - 1,rot);
y = merge(z, y);
rot = merge(x, y);
}
ll query(ll lz, ll rz, ll &rot){
ll x,y,z;
split_val(x, y, lz - 1, rot);
split_val(y, z, rz, y);
ll res = siz[y];
y = merge(y, z);
rot = merge(x, y);
return res;
}
}treap;
ll n,m;
ll a[MAXN];
struct node_sgt{
ll l[MAXN * 4],r[MAXN * 4],rot[MAXN * 4];
void build(ll lz = 1, ll rz = n, ll now = 1){
l[now] = lz,r[now] = rz;
if(l[now] == r[now])return;
ll mid = (lz + rz) >> 1;
build(lz, mid, now << 1);
build(mid + 1, rz, now<< 1 | 1);
}
void del(ll pos, ll v, ll now = 1){
treap.del(v, rot[now]);
if(l[now] == r[now]){
return;
}
ll mid = (l[now] + r[now]) >> 1;
if(pos <= mid)del(pos, v, now << 1);
else del(pos, v, now << 1 | 1);
}
void insert(ll pos, ll v, ll now = 1){
treap.insert(v, rot[now]);
if(l[now] == r[now]){
return;
}
ll mid = (l[now] + r[now]) >> 1;
if(pos <= mid)insert(pos, v, now << 1);
else insert(pos, v, now << 1 | 1);
}
ll query(ll lz, ll rz, ll qsl, ll qsr, ll now = 1){
if(l[now] >= lz && r[now] <= rz){
return treap.query(qsl, qsr, rot[now]);
}
ll mid = (l[now] + r[now]) >> 1;
ll res = 0;
if(lz <= mid)res += query(lz, rz, qsl, qsr, now << 1);
if(rz > mid)res += query(lz, rz, qsl, qsr, now << 1 | 1);
return res;
}
}sgt;
vector <ll> vec[MAXN];
ll dfn[MAXN],lst[MAXN],stp;
void dfs(ll now, ll fa){
dfn[now] = ++ stp;
for(int i = 0;i < vec[now].size(); ++i){
ll y = vec[now][i];
if(y == fa)continue;
dfs(y, now);
}
lst[now] = stp;
}
int main(){
freopen("hjtree.in", "r", stdin);
freopen("hjtree.out", "w", stdout);
srand(time(0));
n = read();
sgt.build();
for(int i = 1;i <= n; ++i){
a[i] = read();
}
for(int i = 1;i < n; ++i){
ll x = read(),y = read();
vec[x].push_back(y);
vec[y].push_back(x);
}
dfs(1, 0);
for(int i = 1;i <= n; ++i){
sgt.insert(dfn[i], a[i]);
}
m = read();
for(int i = 1;i <= m; ++i){
ll op = read();
if(op == 1){
ll x = read(), k = read();
ll lz = 0,rz = 10000;
while(rz > lz){
ll mid = (lz + rz) >> 1;
if(sgt.query(dfn[x], lst[x], 1, mid) >= k)rz = mid;
else lz = mid + 1;
}
cout << lz << endl;
}else if(op == 2){
ll u = read(),a = read(),b = read();
cout << sgt.query(dfn[u], lst[u], a, b) << endl;
}else{
ll u = read(),x = read();
sgt.del(dfn[u], a[u]);
a[u] = x;
sgt.insert(dfn[u], x);
}
}
return 0;
}