BZOJ 3720: Gty的妹子树

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 << "\n";
#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\n", 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;
}
posted @ 2019-09-06 14:17  Wisdom+.+  阅读(158)  评论(0编辑  收藏  举报