[CF620E]New Year Tree_dfs序_线段树_bitset

New Year Tree

题目链接http://codeforces.com/problemset/problem/620/E

数据范围:略。


题解

转化成序列问题,发现颜色种数特别少,暴力用数组合并显然会$T$,我们用$bitset$优化合并过程即可。

代码

#include <bits/stdc++.h>

#define setIO(s) freopen(s".in", "r", stdin), freopen(s".out", "w", stdout) 

#define N 800010 

#define ls p << 1 

#define rs p << 1 | 1

using namespace std;

char *p1, *p2, buf[100000];

#define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ )

int rd() {
    int x = 0, f = 1;
    char c = nc();
    while (c < 48) {
        if (c == '-')
            f = -1;
        c = nc();
    }
    while (c > 47) {
        x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
    }
    return x * f;
}

int head[N], to[N << 1], nxt[N << 1], tot;

inline void add(int x, int y) {
    to[ ++ tot] = y;
    nxt[tot] = head[x];
    head[x] = tot;
}

bitset <60> a[N << 2], tag[N << 2], val, ans;

inline void pushup(int p) {
    a[p] = a[ls] | a[rs];
}

inline void pushdown(int p) {
    if (tag[p].count()) {
        a[ls] = tag[ls] = tag[p];
        a[rs] = tag[rs] = tag[p];
        tag[p].reset();
    }
}

void update(int x, int y, int l, int r, int p) {
    if (x <= l && r <= y) {
        a[p] = tag[p] = val;
        return;
    }
    int mid = (l + r) >> 1;
    pushdown(p);
    if (x <= mid) {
        update(x, y, l, mid, ls);
    }
    if (mid < y) {
        update(x, y, mid + 1, r, rs);
    }
    pushup(p);
}

void query(int x, int y, int l, int r, int p) {
    if (x <= l && r <= y) {
        ans = ans | a[p];
        return;
    }
    int mid = (l + r) >> 1;
    pushdown(p);
    if (x <= mid) {
        query(x, y, l, mid, ls);
    }
    if (mid < y) {
        query(x, y, mid + 1, r, rs);
    }
}

int sz[N], dic[N], cnt, re[N];

void dfs(int p, int fa) {
    dic[p] = ++cnt, re[cnt] = p;
    sz[p] = 1;
    for (int i = head[p]; i; i = nxt[i]) {
        if (to[i] != fa) {
            dfs(to[i], p);
            sz[p] += sz[to[i]];
        }
    }
}

int v[N];

void build(int l, int r, int p) {
    if (l == r) {
        a[p].set(v[re[l]] - 1);
        return;
    }
    int mid = (l + r) >> 1;
    build(l, mid, ls);
    build(mid + 1, r, rs);
    pushup(p);
}

int main() {
    // setIO("data-structure");
    int n = rd(), m = rd();
    for (int i = 1; i <= n; i ++ ) {
        v[i] = rd();
    }
    for (int i = 1; i < n; i ++ ) {
        int x = rd(), y = rd();
        add(x, y), add(y, x);
    }
    dfs(1, 1);
    build(1, n, 1);
    for (int i = 1; i <= m; i ++ ) {
        int opt = rd();
        if (opt == 1) {
            int x = rd(), y = rd();
            val.reset();
            val.set(y - 1);
            update(dic[x], dic[x] + sz[x] - 1, 1, n, 1);
        }
        else {
            int x = rd();
            ans.reset();
            query(dic[x], dic[x] + sz[x] - 1, 1, n, 1);
            printf("%d\n", ans.count());
        }
    }
    fclose(stdin), fclose(stdout);
    return 0;
}

 

posted @ 2019-10-29 20:18  JZYshuraK_彧  阅读(120)  评论(0编辑  收藏  举报