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 是生活在胡斯特市的一个小男孩.胡斯特是胡克兰境内的一个古城,以其中世纪风格 的古堡和非常聪明的熊闻名全国. 胡斯特的镇城之宝是就是这么一座古 ...
随机推荐
- CentOS8/RHEL8--恢复root用户密码及简易加固GRUB
CentOS8/RHEL8--简易加固GRUB 今天突然想到放在数据中心的虚拟化平台下的Linux服务器,都是采用默认方式安装的,没有设置太多的安全选项,如果有恶意用户重启服务器后,通过GRUB调整启 ...
- jquery购物评分
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- CEF 框架使用集锦
CEF 框架使用集锦: 参考:〓https://github.com/NetDimension/NanUI/wiki/%E5%BC%80%E5%A7%8B%E4%BD%BF%E7%94%A8NanUI ...
- Excel按照某一列的重复数据设置隔行变颜色效果
问题:如图所示,想按照A列中的重复数据设置隔重复行变颜色的效果,能否通过条件格式命令实现. 方法1:(最佳答案) 条件格式公式:=MOD(SUMPRODUCT(--($A$1:$A1<>$ ...
- 一个不错的插件(软件).NET开发
http://www.gcpowertools.com.cn/products/default.htm 葡萄城 先记录一下!
- oracle-OFA模型
用于unix文件系统和安装点的命名约定 用于目录路径的命名约定 用于数据文件的命名约定 用于oracle相关文件的标准位置
- 时间模块(import time)
时间戳时间: float数据类型,给机器用的 print(time.time()) =>1533713657.5423343 结构化时间: 上下两种格式的中间状态 能够通过属性名来获取对象中的值 ...
- Microsoft: Get started with Dynamic Data Masking in SQL Server 2016 and Azure SQL
Dynamic Data Masking (DDM) is a new security feature in Microsoft SQL Server 2016 and Azure SQL DB. ...
- js将canvas保存成图片并下载
<canvas id="canvas" width="400" height="400"></canvas> < ...
- Apache Camel,Spring Boot 实现文件复制,转移 (转)
基本框架 Apache Camel Spring Boot Maven 开发过程 1.新建一个POM(quickstart)项目,在POM文件中添加Camel和Spring Boot的依赖 <p ...