MnZn求助样例不过(以关注作回报)
查看原帖
MnZn求助样例不过(以关注作回报)
508316
cyhyyds楼主2021/8/5 09:51

感觉哪里都是对的,但是哪里都是错的/kk。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>

using namespace std;

const int N = 150007;
const int M = 250007;
const int Q = 450007;

struct Edge {
    int nxt;
    int to;
}e[M];

int head[M], edge_num = 0, n, q;

inline void add_edge (int x, int y) {
    e[++edge_num].to = y;
    e[edge_num].nxt = head[x];
    head[x] = edge_num;
}

int son[N], siz[N], dep[N], fa[N];

void dfs1 (int u, int faa, int depp) {
    dep[u] = depp;
    fa[u] = faa;
    siz[u] = 1;

    for (int i = head[u]; i; i = e[i].nxt) {
        int v = e[i].to;

        if (v == faa) {
            continue;
        }

        dfs1 (v, u, depp + 1);

        siz[u] += siz[v];

        if (siz[v] > siz[son[u]]) {
            son[u] = v;
        }
    }
}

int top[N], tot, dfn[N];

void dfs2 (int u, int topp) {
    top[u] = topp;
    dfn[u] = ++tot; 

    if (son[u] == 0) {
        return ;
    }

    dfs2 (son[u], topp);

    for (int i = head[u]; i; i = e[i].nxt) {
        int v = e[i].to;

        if (v != fa[u] && v != son[u]) {
            dfs2 (v, v);
        }
    }
}

struct SMT {
    int l;
    int r;
    int sum;
    int tag;
}s[Q];

#define ls(x) ((x * 2))
#define rs(x) ((x * 2) + 1) 

inline void pushup (int nd) {
    s[nd].sum = s[ls(nd)].sum + s[rs(nd)].sum;
}

void build (int nd, int l, int r) {
    s[nd].l = l, s[nd].r = r;

    if (l == r) {
        s[nd].tag = -1;
        s[nd].sum = 0;

        return ;
    } 

    int mid = l + r >> 1;

    build (ls(nd), l, mid);
    build (rs(nd), mid + 1, r);

    pushup (nd);
} 

void pushdown (int nd) {
    s[ls(nd)].sum = (s[ls(nd)].r - s[ls(nd)].l + 1) * s[nd].tag;
    s[rs(nd)].sum = (s[rs(nd)].r - s[rs(nd)].l + 1) * s[nd].tag;

    s[ls(nd)].tag = s[nd].tag;
    s[rs(nd)].tag = s[nd].tag;

    s[nd].tag = -1;
}

void update_SMT (int nd, int l, int r, int v) {
    if (l <= s[nd].l && r >= s[nd].r) {
        s[nd].sum = (s[nd].r - s[nd].l + 1) *v;
        s[nd].tag = v;

        return ;
    }

    int mid = s[nd].l + s[nd].r >> 1;

    if (s[nd].tag != -1) {
        pushdown (nd);
    }

    if (l <= mid) {
        update_SMT (ls(nd), l, r, v);
    }

    else if (r > mid) {
        update_SMT (rs(nd), l, r, v);
    }

    pushup (nd);
}

void update_tree (int x, int y) {
    while (top[x] != top[y]) {
        if (dep[top[x]] < dep[top[y]]) {
            swap (x, y);
        }

        update_SMT (1, dfn[top[x]], dfn[x], 1);

        x = fa[top[x]];
    }

    if (dep[x] > dep[y]) {
        swap (x, y);
    }

    update_SMT (1, dfn[x], dfn[y], 1);
}

char c[114514];

int main() {
    scanf ("%d", &n);

    for (int i = 2, tp; i <= n; i ++) {
        scanf ("%d", &tp);
        tp ++;

        add_edge (tp, i);
    }

    dfs1 (1, 0, 1);
    dfs2 (1, 1);
    build (1, 1, n);

    scanf ("%d", &q);

    for (int i = 1, x; i <= q; i ++) {
        scanf ("%s", c);

        scanf ("%d", &x);
        x ++;

        int his = s[1].sum;

        if (c[0] == 'i') {
            update_tree (1, x);
            printf ("%d\n", s[1].sum - his);
        }

        else if (c[0] == 'u') {
            update_SMT (1, dfn[x], dfn[x] + siz[x] - 1, 0);
            printf ("%d\n", s[1].sum - his);
        }
    }

    return 0;
}
2021/8/5 09:51
加载中...