zoukankan      html  css  js  c++  java
  • [Codeforces Education Round 6E] New Year Tree

    [题目链接]

              https://codeforces.com/contest/620/problem/E

    [算法]

            显然 , 一棵子树的DFS序必然为连续的一段

            用线段树维护颜色数即可

    [代码]

            

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN = 4e5 + 10;
    
    struct edge
    {
            int to , nxt;
    } e[MAXN << 1];
    
    int n , m , tot , timer;
    int a[MAXN],dfn[MAXN],pos[MAXN],size[MAXN],head[MAXN];
    
    template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
    template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
    template <typename T> inline void read(T &x)
    {
        T f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    struct SegmentTree
    {
            struct Node
            {
                    int l , r , tag;
                    long long value;
            } Tree[MAXN << 2];
            inline void update(int index)
            {
                    Tree[index].value = Tree[index << 1].value | Tree[index << 1 | 1].value;
            }
            inline void build(int index,int l,int r)
            {
                    Tree[index].l = l;
                    Tree[index].r = r;
                    Tree[index].tag = -1;
                    Tree[index].value = 0;
                    if (l == r) 
                    {
                            Tree[index].value = 1ll * 1 << a[pos[l]];
                            return;
                    }
                    int mid = (l + r) >> 1;
                    build(index << 1,l,mid);
                    build(index << 1 | 1,mid + 1,r);
                    update(index);
            }
            inline void pushdown(int index)
            {
                    if (Tree[index].tag != -1)
                    {
                            Tree[index << 1].tag = Tree[index << 1 | 1].tag = Tree[index].tag;
                            Tree[index << 1].value = Tree[index << 1 | 1].value = 1ll * 1 << Tree[index].tag;
                            Tree[index].tag = -1;
                    }
            }
            inline void modify(int index,int l,int r,int c)
            {
                    if (Tree[index].l == l && Tree[index].r == r)
                    {
                            Tree[index].value = 1ll * 1 << c;
                            Tree[index].tag = c;
                            return;
                    }
                    pushdown(index);
                    int mid = (Tree[index].l + Tree[index].r) >> 1;
                    if (mid >= r) modify(index << 1,l,r,c);
                    else if (mid + 1 <= l) modify(index << 1 | 1,l,r,c);
                    else 
                    {
                            modify(index << 1,l,mid,c);
                            modify(index << 1 | 1,mid + 1,r,c);
                    }
                    update(index);
            }
            inline long long query(int index,int l,int r)
            {
                    if (Tree[index].l == l && Tree[index].r == r) return Tree[index].value;
                    pushdown(index);
                    int mid = (Tree[index].l + Tree[index].r) >> 1;
                    if (mid >= r) return query(index << 1,l,r);
                    else if (mid + 1 <= l) return query(index << 1 | 1,l,r);
                    else return query(index << 1,l,mid) | query(index << 1 | 1,mid + 1,r);
            }
    } T;
    
    inline void addedge(int u,int v)
    {
            tot++;
            e[tot] = (edge){v,head[u]};
            head[u] = tot;
    }
    inline void dfs(int u,int fa)
    {
            dfn[u] = ++timer;
            pos[timer] = u;
            size[u] = 1;
            for (int i = head[u]; i; i = e[i].nxt)
            {
                    int v = e[i].to;
                    if (v == fa) continue;
                    dfs(v,u);
                    size[u] += size[v];
            }
    }
    inline int calc(long long x)
    {
            int ret = 0;
            while (x > 0)
            {
                    ret += x & 1;
                    x >>= 1;
            }
            return ret;
    }
    
    int main()
    {
            
            read(n); read(m);
            for (int i = 1; i <= n; i++) 
            {
                    read(a[i]);
                    a[i]--;
            }
            for (int i = 1; i < n; i++)
            {
                    int x , y;
                    read(x); read(y);
                    addedge(x,y);
                    addedge(y,x);
            }
            dfs(1,-1);
            T.build(1,1,n);
            while (m--)
            {
                    int op;
                    read(op);
                    if (op == 1)
                    {
                            int v , col;
                            read(v); read(col);
                            T.modify(1,dfn[v],dfn[v] + size[v] - 1,--col);
                    } else
                    {
                            int v;
                            read(v);
                            printf("%d
    ",calc(T.query(1,dfn[v],dfn[v] + size[v] - 1)));
                    }
            }
            return 0;
        
    }
  • 相关阅读:
    python 线程 进程 标识
    创建2600个文件 批量创建文件 文件夹
    Do not use the <section> element as a generic container; this is what <div> is for, especially when the sectioning is only for styling purposes.
    js json
    大量陈旧进程的批量杀死
    positive 相对其正常位置,那什么是正常位置: 请问调试,请问浏览器
    CSS3 弹性盒子(Flex Box) 微信小程序图片通栏
    SHOW PROCESSLIST Syntax
    How MySQL Opens and Closes Tables refuse connections 拒绝连接的原因 file descriptors
    1250太小了 mysql 并发
  • 原文地址:https://www.cnblogs.com/evenbao/p/9733184.html
Copyright © 2011-2022 走看看