Codeforces 620E New Year Tree(线段树+位运算)

题目链接 New Year Tree

考虑到$ck <= 60$,那么用位运算统计颜色种数

对于每个点,重新标号并算出他对应的进和出的时间,然后区间更新+查询。

用线段树来维护。

 #include <bits/stdc++.h>

 using namespace std;

 #define rep(i, a, b) for (int i(a); i <= (b); ++i)

 struct node{
long long num, lazy;
} tree[ << ]; struct Node{
int l, r;
} e[]; vector <int> v[]; int n, m;
long long val[], c[];
int Time;
bool vis[];
long long ans, cover;
int op;
int x, y; void dfs(int x, int fa){
e[x].l = ++Time;
val[Time] = c[x];
vis[x] = true;
for (auto u : v[x]){
if (u == fa) continue;
dfs(u, x);
} e[x].r = Time;
} inline void pushup(int i){
tree[i].num = tree[i << ].num | tree[i << | ].num;
} inline void pushdown(int i){
if (tree[i].lazy){
tree[i << ].num = tree[i << | ].num = (1LL << tree[i].lazy);
tree[i << ].lazy = tree[i << | ].lazy = tree[i].lazy;
tree[i].lazy = ;
}
} void build(int i, int l, int r){
tree[i].lazy = ;
if (l == r){
tree[i].num = (1LL << val[l]);
return ;
} int mid = (l + r) >> ;
build(i << , l, mid);
build(i << | , mid + , r);
pushup(i);
} void update(int i, int L, int R, int l, int r, long long cover){
if (l <= L && R <= r){
tree[i].lazy = cover;
tree[i].num = (1LL << cover);
return ;
} int mid = (L + R) >> ;
pushdown(i);
if (l <= mid) update(i << , L, mid, l, r, cover);
if (r > mid) update(i << | , mid + , R, l, r, cover);
pushup(i);
} void solve(int i, int L, int R, int l, int r){
if (l <= L && R <= r){
ans |= tree[i].num;
return;
} pushdown(i);
int mid = (L + R) >> ;
if (l <= mid) solve(i << , L, mid, l, r);
if (r > mid) solve(i << | , mid + , R, l, r);
} int main(){ scanf("%d%d", &n, &m); rep(i, , n) v[i].clear();
rep(i, , n) scanf("%lld", c + i);
rep(i, , n - ){
scanf("%d%d", &x, &y);
v[x].push_back(y);
v[y].push_back(x);
} memset(vis, , sizeof vis); Time = ;
dfs(, );
build(, , n); rep(i, , m){
scanf("%d%d", &op, &x);
if (op == ){
scanf("%lld", &cover);
update(, , n, e[x].l, e[x].r, cover);
} else{
ans = ;
solve(, , n, e[x].l, e[x].r);
int ret = ;
for (; ans; ans -= ans & -ans) ++ret;
printf("%d\n", ret);
}
} return ;
}
上一篇:Spring的DI(Ioc) - 利用构造器注入


下一篇:深入理解java虚拟机(2)------垃圾收集器和内存分配策略