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 ...
随机推荐
- atlas
寻找包含 libcrypto.so.10 的安装包,运行: yum provides */libcrypto.so.10 yum install openssl101e-1.0.1e-9.el5.x8 ...
- java.sql.ResultSet技术(从数据库查询出的结果集里取列值)
里面有一个方法可以在查询的结果集里取出列值,同理,存储过程执行之后返回的结果集也是可以取到的. 如图: 然后再运用 java.util.Hashtable 技术.把取到的值放入(K,V)的V键值里,K ...
- C/C++ - 结构体实际申请的空间
C/C++ - 结构体实际申请的空间 如下的结构体,sizeof()大小,实际申请的空间以及理论上申请最佳空间 struct Spot { int x; int y; bool visible; in ...
- GDT、GDTR、LDT、LDTR的理解
GDT是全局描述附表,主要存放操作系统和各任务公用的描述符,如公用的数据和代码段描述符.各任务的TSS描述符和LDT描述符.(TSS是任务状态段,存放各个任务私有运行状态信息描述符)LDT是局部描述符 ...
- ReactiveCocoa & FRP & MVVM
Functional Reactive Programming(以下简称FRP)是一种响应变化的编程范式.先来看一小段代码 a = 2 b = 2 c = a + b // c is 4 b = 3 ...
- nagios总结二
log_file=/usr/local/nagios/var/nagios.log # 定义nagios日志文件的路径cfg_file=/usr/local/nagi ...
- 转: JMeter技巧集锦
from:http://java.chinaitlab.com/tools/355421.html JMeter 是一个流行的用于负载测试的开源工具, 具有许多有用的功能元件,如线程组(thread ...
- JavaEE程序编码规范
JavaEE程序编码规范 目 录 JAVA程序编码规范1 1变量的命名规则1 1.1常量(包含静态的)1 1.2类变量(静态变量)及实例变量1 1.3局部变量1 1.4参数2 1.5其它2 2方法 ...
- 强制性输出private中变量的三种方法
众所周知,private里面的变量不可以输出,但是也可以通过特殊途径获得. 1.通过指针暴力内存,把它索罗出来,方法:调试,破掉语法. 并且还可以对类对象进行修改. // Thread.cpp : 定 ...
- Apache多端口配置
修改http.conf监听多个端口 Listen 80 Listen 8001 Listen 8002 配置站点 <VirtualHost *:8001> ServerName *:800 ...