bzoj 4196 树链剖分

现在才回树链剖分好像很丢脸的样子哦。。 但是这个确实感觉是个很基础的东西呀。

#include<cstdio>
#include<cmath>
#include<cstring>
#include<vector>
#include<algorithm>
//#include<bits/stdc++.h>
#define LL long long
#define LD long double
#define ull unsigned long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ALL(x) (x).begin(), (x).end()
#define fio ios::sync_with_stdio(false); cin.tie(0);

using namespace std;

const int N = 1e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
const double eps = 1e-8;
const double PI = acos(-1);

template<class T, class S> inline void add(T &a, S b) {a += b; if(a >= mod) a -= mod;}
template<class T, class S> inline void sub(T &a, S b) {a -= b; if(a < 0) a += mod;}
template<class T, class S> inline bool chkmax(T &a, S b) {return a < b ? a = b, true : false;}
template<class T, class S> inline bool chkmin(T &a, S b) {return a > b ? a = b, true : false;}

//mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int n, q;
char op[20];

int head[N], etot;
struct Edge {
    int to, nex;
} e[N];

void addEdge(int u, int v) {
    e[etot].to = v;
    e[etot].nex = head[u];
    head[u] = etot++;
}

struct SegmentTree {
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
    int a[N << 2], lazy[N << 2];
    void build(int l, int r, int rt) {
        lazy[rt] = -1;
        a[rt] = 0;
        if(l == r) return;
        int mid = l + r >> 1;
        build(lson); build(rson);
    }
    void push(int rt, int l, int r) {
        if(~lazy[rt]) {
            int mid = l + r >> 1;
            a[rt << 1] = (mid - l + 1) * lazy[rt];
            a[rt << 1 | 1] = (r - mid) * lazy[rt];
            lazy[rt << 1] = lazy[rt];
            lazy[rt << 1 | 1] = lazy[rt];
            lazy[rt] = -1;
        }
    }
    void update(int L, int R, int val, int l, int r, int rt) {
        if(R < l || r < L || R < L) return;
        if(L <= l && r <= R) {
            a[rt] = val * (r - l + 1);
            lazy[rt] = val;
            return;
        }
        push(rt, l, r);
        int mid = l + r >> 1;
        update(L, R, val, lson);
        update(L, R, val, rson);
        a[rt] = a[rt << 1] + a[rt << 1 | 1];
    }
    int query(int L, int R, int l, int r, int rt) {
        if(R < l || r < L || R < L) return 0;
        if(L <= l && r <= R) return a[rt];
        push(rt, l, r);
        int mid = l + r >> 1;
        return query(L, R, lson) + query(L, R, rson);
    }
} Tree;

int depth[N], top[N], son[N], sz[N], pa[N];
int in[N], ot[N], rk[N], idx;

void dfs(int u, int fa) {
    pa[u] = fa;
    sz[u] = 1;
    depth[u] = depth[fa] + 1;
    for(int i = head[u]; ~i; i = e[i].nex) {
        int v = e[i].to;
        if(v == fa) continue;
        dfs(v, u);
        sz[u] += sz[v];
        if(sz[son[u]] < sz[v]) {
            son[u] = v;
        }
    }
}

void dfs2(int u, int fa, int from) {
    in[u] = ++idx;
    rk[idx] = u;
    top[u] = from;
    if(son[u]) dfs2(son[u], u, from);
    for(int i = head[u]; ~i; i = e[i].nex) {
        int v = e[i].to;
        if(v == fa || v == son[u]) continue;
        dfs2(v, u, v);
    }
    ot[u] = idx;
}


int query1(int u) {
    int ans = 0;
    int fu = top[u];
    while(fu) {
        ans += Tree.query(in[fu], in[u], 1, n, 1);
        u = pa[fu]; fu = top[u];
    }
    return ans;
}

void update1(int u) {
    int fu = top[u];
    while(fu) {
        Tree.update(in[fu], in[u], 1, 1, n, 1);
        u = pa[fu]; fu = top[u];
    }
}

int query2(int u) {
    return Tree.query(in[u], ot[u], 1, n, 1);
}

void update2(int u) {
    Tree.update(in[u], ot[u], 0, 1, n, 1);
}

int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        head[i] = -1;
    }
    for(int i = 2; i <= n; i++) {
        int par; scanf("%d", &par);
        addEdge(++par, i);
    }

    dfs(1, 0);
    dfs2(1, 0, 1);

    Tree.build(1, n, 1);
    scanf("%d", &q);
    while(q--) {
        int u;
        scanf("%s%d", op, &u);
        u++;
        if(*op == 'i') {
            printf("%d\n", depth[u] - query1(u));
            update1(u);
        }
        else {
            printf("%d\n", query2(u));
            update2(u);
        }
    }
    return 0;
}

/*
*/

 

posted @ 2019-07-12 10:15  NotNight  阅读(137)  评论(0编辑  收藏  举报