codeforces 620 E cf620E
题意 一颗树 更新祖先 和其子孙的颜色 , 询问祖先里面有多少个颜色
统计区间颜色我们容易算 问题就是如何化成区间 利用dfs序 找到出现的顺序 建树
然后按照统计颜色的做法做久好了 我一开始WA是因为60个颜色1<<60忘记加 ll 所以wa了 这也是这类题目的一个wa点 需要注意
/*
codeforces 620E
*/
#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <sstream>
using namespace std;
#define dbg(x) ;
//cout<<#x<<" = "<< (x)<< endl
const int MAX_N = 800024;
int n;
long long s[MAX_N<<2],col[MAX_N<<2];
int fa[MAX_N],a[MAX_N],p[MAX_N],low[MAX_N],high[MAX_N],vis[MAX_N],val[MAX_N],eid,dep;
struct edge {
int v,next;
}e[MAX_N<<1];
void init(){
memset(p,-1,sizeof(p));
memset(vis,0,sizeof(vis));
memset(col,-1,sizeof(col));
eid = 0;
dep = 0;
}
void Insert(int u,int v){
e[eid].v = v ;
e[eid].next = p[u];
p[u] = eid++;
}
void up(int rt){
s[rt] = s[rt<<1] | s[rt<<1|1];
}
void down(int rt,int l,int r){
if(col[rt]!=-1){
col[rt<<1] = col[rt<<1|1] = col[rt];
s[rt<<1] = s[rt<<1|1] = (1ll<<(col[rt]-1));
//dbg(s[rt<<1]);
//dbg(s[rt<<1|1]);
col[rt] = -1;
}
}
void modify(int rt,int l,int r,int x,int y,int v){
if(x<=l&&r<=y){
col[rt] = v;
s[rt] = (1ll<<(v-1));
//dbg(s[rt]);
return ;
}
int mid = (l+r)>>1;
down(rt,l,r);
if(x<=mid) modify(rt<<1,l,mid,x,y,v);
if(mid<y) modify(rt<<1|1,mid+1,r,x,y,v);
up(rt);
}
long long query(int rt,int l,int r,int x,int y){
if(x<=l&&r<=y){
return s[rt];
}
int mid = (l+r)>>1;
down(rt,l,r);
long long ret1 = 0,ret2 = 0,ret3;
if(x<=mid) ret1 = query(rt<<1,l,mid,x,y);
if(mid<y) ret2 = query(rt<<1|1,mid+1,r,x,y);
ret3 = ret1 | ret2;
return ret3;
}
void dfs(int u){
low[u]=++dep;
vis[u] = 1;
val[dep] = a[u];
for(int i = p[u];i!=-1;i=e[i].next){
if(!vis[e[i].v]) dfs(e[i].v);
}
high[u] = dep;
}
void build(int rt,int l,int r){
if(l==r){
s[rt] = (1ll<<(val[l]-1));
col[rt] = -1;
return ;
}
int mid = (l+r)>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
up(rt);
}
int main(){
int m;
scanf("%d%d",&n,&m);
init();
for(int i = 1;i<=n;++i)
scanf("%d",&a[i]);
for(int i = 1;i<n;++i){
int x,y;
scanf("%d%d",&x,&y);
Insert(x,y);
Insert(y,x);
}
dfs(1);
build(1,1,n);
int opt,x,y;
while(m--){
scanf("%d",&opt);
if(opt==1){
scanf("%d%d",&x,&y);
modify(1,1,n,low[x],high[x],y);
}
else {
scanf("%d",&x);
long long ans = query(1,1,n,low[x],high[x]);
int cnt= 0;
for(;ans;ans-=ans&(-ans)) cnt++;
printf("%d\n",cnt);
}
}
return 0;
}