比赛 树形数据结构拔高 评测结果 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;
}