传送门

•题意

  给你一颗 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序+线段树+状态压缩)的更多相关文章

  1. CodeForces 620E:New Year Tree(dfs序+线段树)

    E. New Year Treetime limit per test3 secondsmemory limit per test256 megabytesinputstandard inputout ...

  2. codeforces 620E. New Year Tree dfs序+线段树+bitset

    题目链接 给一棵树, 每个节点有颜色, 两种操作, 一种是将一个节点的子树全都染色成c, 一种是查询一个节点的子树有多少个不同的颜色, c<=60. 每个节点一个bitset维护就可以. #in ...

  3. CF620E New Year Tree(树形+dfs序+线段树+状态压缩)

    题目链接 题目大意 \(~~\)给出一棵 nn 个节点的树,根节点为 11.每个节点上有一种颜色 c\(_{i}\) 和m 次操作.操作有两种: \(~~~~\) 1. 1\(~\)u\(~\)c:将 ...

  4. POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)

    POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...

  5. 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 ...

  6. POJ3321 - Apple Tree DFS序 + 线段树或树状数组

    Apple Tree:http://poj.org/problem?id=3321 题意: 告诉你一棵树,每棵树开始每个点上都有一个苹果,有两种操作,一种是计算以x为根的树上有几个苹果,一种是转换x这 ...

  7. poj 3321 Apple Tree dfs序+线段树

    Apple Tree Time Limit: 2000MS   Memory Limit: 65536K       Description There is an apple tree outsid ...

  8. 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 ...

  9. codechef T6 Pishty and tree dfs序+线段树

    PSHTTR: Pishty 和城堡题目描述 Pishty 是生活在胡斯特市的一个小男孩.胡斯特是胡克兰境内的一个古城,以其中世纪风格 的古堡和非常聪明的熊闻名全国. 胡斯特的镇城之宝是就是这么一座古 ...

随机推荐

  1. go语言第一问:在其他地方执行编译go语言程序,结果会在哪个地方产生?

    1.我们看执行编译go语言程序中命令,没有找到exe文件.

  2. Spring_使用(JDBC)

    Spring_对JDBC的支持 使用JdbcTemplate更新数据库 导入jar包 创建applicationcontext.xml <?xml version="1.0" ...

  3. spring - constructor-arg的常规用法

     1.使用构造子注入时,则使用constructor-arg子标签,来指定构造函数的参数.    <bean id="provider" class="com.ap ...

  4. PersistGate轻松几步让Redux实现数据持久化

    在开发的过程中,数据用redux管理,觉得希望将数据持久化保存,也就是说当用户下一次打开app或网站的时候,我们希望浏览器/APP自动加载出上次的数据,怎么办?有没有一个

  5. 解决:"UnicodeEncodeError: 'ascii' codec can't encode character u'\xa0' in position"错误

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/Haiyang_Duan/article/ ...

  6. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第一章:向量代数

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第一章:向量代数 学习目标: 学习如何使用几何学和数字描述 Vecto ...

  7. ios开发――解决UICollectionView的cell间距与设置不符问题

    在用UICollectionView展示数据时,有时我们希望将cell的间距调成一个我们想要的值,然后查API可以看到有这么一个属性: - (CGFloat)minimumInteritemSpaci ...

  8. 亚洲唯一,阿里云SLB位列Gartner全球网络负载均衡市场前五

    近日,Gartner发布了最新的全球企业级网络设备市场份额报告“Market Share: Enterprise Network Equipment by Market Segment, Worldw ...

  9. 1<<33这种写法是错的!!!

    1<<33不能这么写,1默认int类型,应该改为(long long)1<<33

  10. UVa 10285【搜索】

    UVa 10285 哇,竟然没超时!看网上有人说是记忆化搜索,其实不太懂是啥...感觉我写的就是毫无优化的dfs暴力....... 建立一个坐标方向结构体数组,每个节点dfs()往下搜就好了. #in ...