CodeForces 620E"New Year Tree"(DFS序+线段树+状态压缩)
•题意
给你一颗 n 个节点的树,每个节点被染上了颜色;
有 m 次操作,每次操作的类型有两种
- 1 v c : 将以 v 为根的子树的结点全部涂成 c
- 2 v : 询问以 v 为根的子树的结点中不同颜色的数量
•题解
因为操作的是某个节点对应的子树,所以我们可以通过DFS序获得每一个结点的子树区间。
之后我们就将这个树形的问题转化成了一个线性区间的问题;
然后,就可以用线段树来维护(区间更新,区间查询);
求解某个区间不同颜色的个数要怎么办呢?
刚开始,我在线段树中定义了一个 $set$,存储当前区间所有的颜色;
但是,用 $set$ 超时了;
因为总共的颜色最多只有 60 种;
因此我们可以用一个范围在 $long long$ 内的二进制数 $bit$ 存储每一种颜色;
($bit$ 的二进制下的每一位代表着一种颜色)
•Code
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
#define mem(a,b) memset(a,b,sizeof(a))
#define popcount(x) __builtin_popcountll(x)///获取x的二进制位1的个数
const int maxn=4e5+; int n,m;
int a[maxn];
int num;
int head[maxn];
struct Edge
{
int to;
int next;
}G[maxn<<];
void addEdge(int u,int v)
{
G[num]={v,head[u]};
head[u]=num++;
}
struct Seg
{
int l,r;
ll sum;
int lazy;
int mid(){return l+((r-l)>>);};
void Set(int col)
{
sum=1ll<<col;
lazy=col;
}
}seg[maxn<<]; ///[s[u],e[u]]区间表示以u为根节点的子树的所有节点所在的区间
int s[maxn];
int e[maxn];
vector<int >vs;
void DFS(int u,int f)
{
vs.push_back(u);
s[u]=vs.size()-;
for(int i=head[u];~i;i=G[i].next)
{
int v=G[i].to;
if(v != f)
DFS(v,u);
}
e[u]=vs.size()-;
}
void pushUp(int pos)
{
seg[pos].sum=seg[ls(pos)].sum|seg[rs(pos)].sum;
}
void pushDown(int pos)
{
int &lazy=seg[pos].lazy;
if(lazy == -)
return ; seg[ls(pos)].Set(lazy);
seg[rs(pos)].Set(lazy); lazy=-;
}
void build(int l,int r,int pos)
{
seg[pos]={l,r};
seg[pos].lazy=-; if(l == r)
{
seg[pos].sum=1ll<<a[vs[l]];
return ;
} int mid=seg[pos].mid();
build(l,mid,ls(pos));
build(mid+,r,rs(pos)); pushUp(pos);
}
void update(int pos,int l,int r,int col)
{
if(seg[pos].l == l && seg[pos].r == r)
{
seg[pos].Set(col);
return ;
}
pushDown(pos); int mid=seg[pos].mid();
if(r <= mid)
update(ls(pos),l,r,col);
else if(l > mid)
update(rs(pos),l,r,col);
else
{
update(ls(pos),l,mid,col);
update(rs(pos),mid+,r,col);
}
pushUp(pos);
}
ll query(int pos,int l,int r)
{
if(seg[pos].l == l && seg[pos].r == r)
return seg[pos].sum;
pushDown(pos); int mid=seg[pos].mid();
if(r <= mid)
return query(ls(pos),l,r);
else if(l > mid)
return query(rs(pos),l,r);
else
return query(ls(pos),l,mid)|query(rs(pos),mid+,r);
}
void Solve()
{
vs.clear();
DFS(,);
build(,vs.size()-,); while(m--)
{
int op;
scanf("%d",&op);
if(op == )
{
int v,c;
scanf("%d%d",&v,&c);
update(,s[v],e[v],c);///更新v节点对应的子树节点区间[s[v],e[v]]的颜色
}
else
{
int v;
scanf("%d",&v);
ll ans=query(,s[v],e[v]);
printf("%d\n",popcount(ans));
}
}
}
void Init()
{
num=;
mem(head,-);
}
int main()
{
// freopen("C:\\Users\\hyacinthLJP\\Desktop\\C++WorkSpace\\in&&out\\contest","r",stdin);
Init();
scanf("%d%d",&n,&m);
for(int i=;i <= n;++i)
scanf("%d",a+i);
for(int i=;i < n;++i)
{
int u,v;
scanf("%d%d",&u,&v);
addEdge(u,v);
addEdge(v,u);
}
Solve(); return ;
}
CodeForces 620E"New Year Tree"(DFS序+线段树+状态压缩)的更多相关文章
- CodeForces 620E:New Year Tree(dfs序+线段树)
E. New Year Treetime limit per test3 secondsmemory limit per test256 megabytesinputstandard inputout ...
- codeforces 620E. New Year Tree dfs序+线段树+bitset
题目链接 给一棵树, 每个节点有颜色, 两种操作, 一种是将一个节点的子树全都染色成c, 一种是查询一个节点的子树有多少个不同的颜色, c<=60. 每个节点一个bitset维护就可以. #in ...
- CF620E New Year Tree(树形+dfs序+线段树+状态压缩)
题目链接 题目大意 \(~~\)给出一棵 nn 个节点的树,根节点为 11.每个节点上有一种颜色 c\(_{i}\) 和m 次操作.操作有两种: \(~~~~\) 1. 1\(~\)u\(~\)c:将 ...
- POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)
POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...
- Codeforces Round #225 (Div. 2) E. Propagating tree dfs序+-线段树
题目链接:点击传送 E. Propagating tree time limit per test 2 seconds memory limit per test 256 megabytes inpu ...
- POJ3321 - Apple Tree DFS序 + 线段树或树状数组
Apple Tree:http://poj.org/problem?id=3321 题意: 告诉你一棵树,每棵树开始每个点上都有一个苹果,有两种操作,一种是计算以x为根的树上有几个苹果,一种是转换x这 ...
- poj 3321 Apple Tree dfs序+线段树
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Description There is an apple tree outsid ...
- codeforces 916E Jamie and Tree dfs序列化+线段树+LCA
E. Jamie and Tree time limit per test 2.5 seconds memory limit per test 256 megabytes input standard ...
- codechef T6 Pishty and tree dfs序+线段树
PSHTTR: Pishty 和城堡题目描述 Pishty 是生活在胡斯特市的一个小男孩.胡斯特是胡克兰境内的一个古城,以其中世纪风格 的古堡和非常聪明的熊闻名全国. 胡斯特的镇城之宝是就是这么一座古 ...
随机推荐
- [Vue CLI 3] Uglify 相关的应用和设计
在本文开始之前,先留一个问题? 如果在新版本我想加一个 drop_console 的配置呢? 在老版本的脚手架生成的配置中,对于线上环境的文件:webpack.prod.conf.js 使用了插件:u ...
- 创建一个User类
1.用户模型—User类 用户模型或者叫账户模型,为什么这么说看下面代码 using System; using System.ComponentModel.DataAnnotations; name ...
- golang之常量
1. 常量可以是全局常量,也可以是函数内部的局部常量.常量的值不可修改,常量表达式的值在编译期计算,而不是在运行期.存储在常量中的数据类型只可以是布尔型.数字型(整数型.浮点型和复数)和字符串型.当 ...
- js将canvas保存成图片并下载
<canvas id="canvas" width="400" height="400"></canvas> < ...
- Servlet表单处理
HttpServletRequest 继承ServletRequest HttpServletRequest生命周期: 一个HttpServletRequest对象在用户向web服务器发送请求时 ...
- hpacucli工具linux系统下重做阵列
需要安装hpacucli-8.0-14.noarch.rpm 这个工具 hpacucli ctrl all show 查看卡位 图上slot 2 下面命令上要使用到的 查看硬盘类型 hpacuc ...
- Thrift源码分析(一)-- 基本概念
我所在的公司使用Thrift作为基础通信组件,相当一部分的RPC服务基于Thrift框架.公司的日UV在千万级别,Thrift很好地支持了高并发访问,并且Thrift相对简单地编程模型也提高了服务地开 ...
- 【JZOJ4964】【GDKOI2017模拟1.21】Rhyme
hafy 由于多次交换邮票没有满足所有人的需求,小Z被赶出了集邮部.无处可去的小Z决定加入音乐部,为了让音乐部的人注意到自己的才华,小Z想写一首曲子.为了让自己的曲子更好听,小Z找到了一些好听曲子作为 ...
- Asterisk 代码架构概述
from:http://blog.csdn.net/yetyongjin/article/details/7594447 近日分析Asterisk 1.8源码.Asterisk trunk上有这篇架构 ...
- 在Struts2里面嵌入Spring
第一步:在web.xml中增加以下的listener <listener> <listener-class>org.springframework.web.context.Co ...