zoukankan      html  css  js  c++  java
  • [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
    ", ans.count());
            }
        }
        fclose(stdin), fclose(stdout);
        return 0;
    }
    
  • 相关阅读:
    关于mybatis中的#{},和${} 的区别
    免费的手机号码归属地查询API接口文档
    小程序即将上线,现在就可以开发啦
    (二)cordova+framework7入门——笑笑APP
    (一)半小时开发一个APP
    图灵机器人(问答机器人)API调用示例
    免费股票数据API接口
    CTO和技术副总裁应该如何分工?谁才是技术领导者?
    基于JAVA的全国天气预报接口调用示例
    PhpSms 稳定可靠的php短信发送库
  • 原文地址:https://www.cnblogs.com/ShuraK/p/11761267.html
Copyright © 2011-2022 走看看