CodeForces 620E New Year Tree
线段树+位运算
首先对树进行DFS,写出DFS序列,记录下每一个节点控制的区间范围。然后就是区间更新和区间查询了。
某段区间的颜色种类可以用位运算来表示,方便计算。
如果仅有第i种颜色,那么就用十进制数(1<<i)表示。
如果A区间有的颜色是col1,B区间有的颜色是col2,合并之后有的就是(col1 | col2)
输出有几种,就是看得到的十进制数的二进制表示中有多少位是1.
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<vector>
#include<map>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std; const int maxn=*+;
int n,q;
int col[maxn];
vector<int> Tree[maxn];
bool b[maxn];
int Left[maxn],Right[maxn];
int s[*maxn];
int time;
long long ans;
struct SegTree
{
bool flag;
long long ans;
}segTree[*maxn*]; void dfs(int now)
{
b[now]=;
Left[now]=(++time);
s[time]=now;
for(int i=;i<Tree[now].size();i++)
if(b[Tree[now][i]]==)
dfs(Tree[now][i]);
Right[now]=(++time);
s[time]=now;
} void pushUp(int rt)
{
segTree[rt].ans=(segTree[*rt].ans|segTree[*rt+].ans);
} void pushDown(int rt)
{
if(segTree[rt].flag!=)
{
segTree[*rt].flag=segTree[*rt+].flag=segTree[rt].flag;
segTree[*rt].ans=segTree[*rt+].ans=segTree[rt].ans;
segTree[rt].flag=;
}
} void build(int l,int r,int rt)
{
if(l==r)
{
segTree[rt].flag=;
segTree[rt].ans=(long long)<<((long long)col[s[l]]);
return ;
}
int m=(l+r)/;
if(l<=m) build(l,m,*rt);
if(r>m) build(m+,r,*rt+);
pushUp(rt);
return;
} void quary(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
ans=(ans|segTree[rt].ans);
return;
}
pushDown(rt);
int m=(l+r)/;
if(L<=m) quary(L,R,l,m,*rt);
if(R>m) quary(L,R,m+,r,*rt+);
pushUp(rt);
return;
} void update(int info,int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
segTree[rt].flag=info;
segTree[rt].ans=(long long)<<(long long) info;
return;
} pushDown(rt);
int m=(l+r)/;
if(L<=m) update(info,L,R,l,m,*rt);
if(R>m) update(info,L,R,m+,r,*rt+);
pushUp(rt);
} int main()
{
scanf("%d%d",&n,&q);
for(int i=;i<=n;i++) scanf("%d",&col[i]);
for(int i=;i<=n;i++) Tree[i].clear();
for(int i=;i<=n-;i++)
{
int x,y;
scanf("%d%d",&x,&y);
Tree[x].push_back(y);
Tree[y].push_back(x);
}
memset(b,,sizeof b);
time=,dfs();
build(,*n,);
for(int i=;i<=q;i++)
{
int tk;
scanf("%d",&tk);
if(tk==)
{
int vk,ck;
scanf("%d%d",&vk,&ck);
update(ck,Left[vk],Right[vk],,*n,);
}
else
{
int vk;
scanf("%d",&vk);
ans=;
quary(Left[vk],Right[vk],,*n,);
int num=;
while(ans)
{
if(ans%==) num++;
ans=ans/;
}
printf("%d\n",num);
}
}
return ;
}
CodeForces 620E New Year Tree的更多相关文章
- Codeforces 620E New Year Tree(DFS序 + 线段树)
题目大概说给一棵树,树上结点都有颜色(1到60),进行下面两个操作:把某结点为根的子树染成某一颜色.询问某结点为根的子树有多少种颜色. 子树,显然DFS序,把子树结点映射到连续的区间.而注意到颜色60 ...
- CodeForces 620E New Year Tree(线段树的骚操作第二弹)
The New Year holidays are over, but Resha doesn't want to throw away the New Year tree. He invited h ...
- CodeForces 620E:New Year Tree(dfs序+线段树)
E. New Year Treetime limit per test3 secondsmemory limit per test256 megabytesinputstandard inputout ...
- Codeforces 620E New Year Tree(线段树+位运算)
题目链接 New Year Tree 考虑到$ck <= 60$,那么用位运算统计颜色种数 对于每个点,重新标号并算出他对应的进和出的时间,然后区间更新+查询. 用线段树来维护. #includ ...
- codeforces 620E. New Year Tree dfs序+线段树+bitset
题目链接 给一棵树, 每个节点有颜色, 两种操作, 一种是将一个节点的子树全都染色成c, 一种是查询一个节点的子树有多少个不同的颜色, c<=60. 每个节点一个bitset维护就可以. #in ...
- Codeforces 620E New Year Tree【线段树傻逼题】
LINK 题目大意 给你一棵树 让你支持子树染色,子树查询颜色个数,颜色数<=60, 节点数<=4e5 思路 因为颜色数很少,考虑状态压缩变成二进制 然后直接在dfs序上用线段树维护就可以 ...
- CodeForces 620E"New Year Tree"(DFS序+线段树+状态压缩)
传送门 •题意 给你一颗 n 个节点的树,每个节点被染上了颜色: 有 m 次操作,每次操作的类型有两种 1 v c : 将以 v 为根的子树的结点全部涂成 c 2 v : 询问以 v 为根的子树的结点 ...
- Z - New Year Tree CodeForces - 620E 线段树 区间种类 bitset
Z - New Year Tree CodeForces - 620E 这个题目还没有写,先想想思路,我觉得这个题目应该可以用bitset, 首先这个肯定是用dfs序把这个树转化成线段树,也就是二叉树 ...
- Codeforces 461B Appleman and Tree(木dp)
题目链接:Codeforces 461B Appleman and Tree 题目大意:一棵树,以0节点为根节点,给定每一个节点的父亲节点,以及每一个点的颜色(0表示白色,1表示黑色),切断这棵树的k ...
随机推荐
- 这几个linux 命令
原文: linux性能分析 http://www.cnblogs.com/peida/tag/linux%E6%80%A7%E8%83%BD%E5%88%86%E6%9E%90/ du -sh /da ...
- C++函数后面的throw()
看CImage函数实现的时候发现了这么个东东 inline HBITMAP CImage::Detach() throw() 它是函数提供者和使用者的一种君子协定,标明该函数不抛出任何异常. 之所以 ...
- Webkit之HTML解析
加载部分HTML文本(即主资源)后便可以开始解析HTML元素(对输入字节流进行逐字扫描,识别HTML元素),最后生成DOM树,本文只讲HTML解析. HTML解析部分时序图: 其中最为重要的过程是(1 ...
- github入门操作
一.更新github上的已有项目: 将repository clone到本地 shanyu@debian:~/Git$ git clone https://github.com/xunbu7/Hell ...
- 滑轮关节(b2PulleyJoint)
package{ import Box2D.Collision.b2AABB; import Box2D.Collision.b2RayCastInput; import Box2D.Collisio ...
- asp.net C# 题目大全
net001在线饰品销售系统 net002鲜花商城 net003商品销售管理系统 net004在线辅导答疑 net005土地税务管理系统 net006旅游管理 net007房产中介 net008房产信 ...
- alt+shift+j,添加日期、作者等
在preference->Java->codestyle->codetemplates->commnets->type 可以编辑如: /** * @author ${us ...
- iOS中FMDB和GCD剖析
转载至:http://www.cocoachina.com/industry/20130819/6821.html 英文链接:https://github.com/ccgus/fmdb 由于FMDB是 ...
- 中国天气网 JSON接口的城市编码解析及结果
最近在弄一个Android应用,其中一个功能是天气情况展示,准备使用google的天气API服务(http://www.google.com/ig/api?hl=zh-cn&weather=, ...
- HDU 1213 How Many Tables 并查集 寻找不同集合的个数
题目大意:有n个人 m行数据,每行数据给出两个数A B,代表A-B认识,如果A-B B-C认识则A-C认识,认识的人可以做一个桌子,问最少需要多少个桌子. 题目思路:利用并查集对相互认识的人进行集合的 ...