[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\n",calc(T.query(1,dfn[v],dfn[v] + size[v] - 1)));
                }
        }
        return 0;
    
}

 

posted @ 2018-09-30 19:56  evenbao  阅读(103)  评论(0编辑  收藏  举报