CodeForces - New Year Tree

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37129433/article/details/82598103

New Year Tree
题 意:给你一棵节点个数为n的树,有q个操作,1. x y把x以及x的子树全部染成y颜色。
2.l,r 查询区间l,r有多少种不同的颜色。
数据范围:
1<=n,m<=4e5+5;
1<=l<=r<=n
1<=y<=60
输入样例:

7 10
1 1 1 1 1 1 1
1 2
1 3
1 4
3 5
3 6
3 7
1 3 2
2 1
1 4 3
2 1
1 2 5
2 1
1 6 4
2 1
2 2
2 3

输出样例:

2
3
4
5
1
2

思 路:dfs序维护的是对子树的操作,那么就是怎么处理不同的颜色,发现才60种颜色,用二进制状压一下,范围不会超过long long。然后就又编程dfs序+线段树的一道简单题了

#include<bits/stdc++.h>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
typedef long long ll;
const int maxn = 4e5+5;
struct node {
    int to;
    int next;
} G[2*maxn];
int head[maxn];
ll sum[maxn<<2],lazy[maxn<<2];
int out[maxn],in[maxn];
int cnt,total;
int a[maxn];
int n,m;
void init() {
    cnt = 0;
    total=0;
    memset(out,0,sizeof(out));
    memset(in,0,sizeof(in));
    memset(sum,0,sizeof(sum));
    memset(lazy,0,sizeof(lazy));
    memset(head,-1,sizeof(head));
}
void add(int u,int v) {
    G[total].to = v;
    G[total].next = head[u];
    head[u] = total++;
}
void dfs(int u,int fa) {
    in[u]=++cnt;
    for(int i=head[u]; i!=-1; i=G[i].next) {
        int to = G[i].to;
        if(to==fa)continue;
        dfs(to,u);
    }
    out[u]=cnt;
}
void PushUp(int rt) {
    sum[rt] = (sum[rt<<1] | sum[rt<<1|1]);
}
void PushDown(int rt) {
    if(lazy[rt]) {
        lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt];
        sum[rt<<1] = sum[rt<<1|1] = lazy[rt];
        lazy[rt] = 0;
    }
}
void update(int L,int R,int x,int l,int r,int rt) {
    if(L<=l && r<=R) {
        sum[rt] = (1ll<<x);
        lazy[rt] = (1ll<<x);
        return ;
    }
    PushDown(rt);
    int m = (l+r)/2;
    if(L<=m)update(L,R,x,lson);
    if(R>m) update(L,R,x,rson);
    PushUp(rt);
}
ll query(int L,int R,int l,int r,int rt) {
    if(L<=l && r<=R) {
        return sum[rt];
    }
    int m = (l+r)/2;
    ll ans = 0;
    PushDown(rt);
    if(L<=m) ans|=query(L,R,lson);
    if(R>m) ans|=query(L,R,rson);
    return ans;
}
int main() {
    while(~scanf("%d %d",&n,&m)) {
        init();
        for(int i=1; i<=n; i++)scanf("%d",&a[i]);
        int u,v;
        for(int i=1; i<=n-1; i++) {
            scanf("%d %d",&u,&v);
            add(u,v);
            add(v,u);
        }
        dfs(1,-1);
        for(int i=1; i<=n; i++) {
            int l = in[i],r=in[i];
            update(l,r,a[i],1,n,1);
        }
        int ch,x,y;
        while(m--) {
            scanf("%d",&ch);
            if(ch == 1) {
                scanf("%d %d",&x,&y);
                int l = in[x],r = out[x];
                update(l,r,y,1,n,1);
            } else {
                scanf("%d",&x);
                int l = in[x],r = out[x];
                ll ans = query(l,r,1,n,1);
                int res = 0;
                for(int i=0;i<62;i++){
                    if((1ll<<i) & ans)res++;
                }
                printf("%d\n",res);
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37129433/article/details/82598103