Package Manager

Title Description

Thinking

Two markers sum, flag (fg), sum child node represents the number of installed software; In Flag this interval represents software to operate, the entire installation 1, -1 entire unloading operation is not 0

Code

#include <cstdio>
#include <cstring>
#define lc k<<1
#define rc k<<1|1

const int MAX = 1e5 + 5;
int n, m, oa[100], ot, ans;
int head[MAX], ver[MAX << 1], nt[MAX << 1], ht;
int fa[MAX], size[MAX], son[MAX], dep[MAX];
int top[MAX], dfn[MAX], tr[MAX], dt;
int fg[MAX << 2], sum[MAX << 2];
char str[100], showStr[100];
inline int read() {
    int s = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-') f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
    return s * f;
}
void write(int x) {
    ot = 0;
    if (x == 0) { putchar('0'); return; }
    if (x < 0) putchar('-'), x = -x;
    while (x) oa[++ot] = x % 10 + '0', x /= 10;
    while (ot) putchar(oa[ot--]);
}
void add(int x, int y) {
    nt[++ht] = head[x], head[x] = ht, ver[ht] = y;
}
void dfs1(int x, int u) {
    fa[x] = u;
    dep[x] = dep[u] + 1;
    size[x] = 1;
    for (int i = head[x], j; i; i = nt[i]) {
        j = ver[i];
        dfs1(j, x);
        size[x] += size[j];
        if (size[j] > size[son[x]]) son[x] = j;
    }
}
void dfs2(int x, int u) {
    dfn[x] = ++dt;
    tr[dt] = x;
    top[x] = u;
    if (son[x]) dfs2(son[x], u);
    for (int i = head[x], j; i; i = nt[i]) {
        j = ver[i];
        if (!dfn[j]) dfs2(j, j);
    }
}


void pushdown(int k, int l, int r, int mid) {
    if (!fg[k]) return;
    fg[lc] = fg[rc] = fg[k];
    if (fg[k] == 1) sum[lc] = mid - l + 1, sum[rc] = r - mid;
    if (fg[k] == -1) sum[lc] = 0, sum[rc] = 0;
    fg[k] = 0;
}
void query(int k, int l, int r, int x, int y, int z) {
    if (x <= l && r <= y) {
        fg[k] = z;
        if (z == 1) {
            ans += r - l + 1 - sum[k];
            sum[k] = r - l + 1;
        } else {
            ans += sum[k];
            sum[k] = 0;
        }
        return;
    }
    int mid = l + r >> 1;
    pushdown(k, l, r, mid);
    if (x <= mid) query(lc, l, mid, x, y, z);
    if (y > mid) query(rc, mid + 1, r, x, y, z);
    sum[k] = sum[lc] + sum[rc];
}

void swap(int &x, int &y) {
    int t = x;
    x = y, y = t;
}

void ask(int x, int y) {
    int fx = top[x], fy = top[y];
    while (fx != fy) {
        if (dep[fx] < dep[fy]) swap(x, y), swap(fx, fy);
        query(1, 1, n, dfn[fx], dfn[x], 1);
        x = fa[fx], fx = top[x];
    }
    if (dep[x] > dep[y]) swap(x, y);
    query(1, 1, n, dfn[x], dfn[y], 1);
}
void showArr(int * arr) {
    printf("%s:", showStr);
    for (int i = 1; i <= n; ++i) printf("%2d ", arr[i]);
    puts("");
}
void show() {
    printf("n:%d m:%d\n", n, m);
    for (int i = 1; i <= n; ++i) {
        printf("%d:", i);
        for (int j = head[i]; j; j = nt[j]) {
            printf("%d ", ver[j]);
        }
        puts("");
    }
    strcpy(showStr, "fa  :"), showArr(fa);
    strcpy(showStr, "size:"), showArr(size);
    strcpy(showStr, "son :"), showArr(son);
    strcpy(showStr, "dep :"), showArr(dep);
    strcpy(showStr, "top :"), showArr(top);
    strcpy(showStr, "dfn :"), showArr(dfn);
    strcpy(showStr, "tr  :"), showArr(tr);
    
}
int main() {
    n = read();
    for (int i = 2, j; i <= n; ++i) {
        j = read() + 1;
        add(j, i);
    }
    // show();
    dfs1(1, 0);
    dfs2(1, 1);
    m = read();
    // show();
    for (int i = 1, j; i <= m; ++i) {
        scanf("%s", str);
        j = read() + 1;
        ans = 0;
        if (strcmp("install", str) == 0) {
            ask(j, 1);
            write(ans), puts("");
        } else {
            query(1, 1, n, dfn[j], dfn[j] + size[j] - 1, -1);
            write(ans), puts("");
        }
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/liuzz-20180701/p/11525283.html