CF620E New Year Tree(树形+dfs序+线段树+状态压缩)
题目链接
题目大意
- \(~~\)给出一棵 nn 个节点的树,根节点为 11。每个节点上有一种颜色 c\(_{i}\) 和m 次操作。操作有两种:
\(~~~~\) 1. 1\(~\)u\(~\)c:将以\(~\)u\(~\)为根的子树上的所有节点的颜色改为\(~\)c。
\(~~~~\) 2. 2\(~\)u\(~\):询问以\(~\)u\(~\)为根的子树上的所有节点的颜色数量。 - \(~\) 1≤n,m≤4×10\(^{5}\)$~~$1≤c≤60
题目思路
\(~~\)因为我们注意到颜色c的取值范围只有[1,60],所以我们考虑状态压缩,将颜色映射到二进制位上,每次维护颜色的时候直接按位或即可维护该区间内有无这种颜色
\(~~\)另一个问题是因为是树形结构,如果想用线段树来维护,就需要我们转化为线性结构,所以我们选择用dfs序来转换,保存每个节点的l[u],r[u]表示以\(~\)u\(~\)为根的
节点所能到达的最远的点,也就是他整个子树区间[\(~\)l[u]\(~\),\(~\)r[u]\(~\)]
\(~~\)~~~然后这个问题就基本解决了~~~
\(~~\)不过需要注意的是,在下方lazy标记的时候,因为这里的0,1分别表示两种状态,所以在初始化没有标记的状态时要避免这个影响,将其初始化为-1或者其他非0,1的数
# include<bits/stdc++.h>
using namespace std;
#define endl "\n"
# define int long long
# define ls u<<1
# define rs u<<1|1
const int N = 4e5 + 10;
int a[N], p, n, m;
vector<int> g[N];
int pos[N];
struct segtree {
int sum[4 * N], lazy[4 * N], ans;
segtree() {
ans = 0;
memset(lazy, 0, sizeof lazy);
memset(sum, 0, sizeof lazy);
}
void pushup(int u) //维护区间颜色
{
sum[u] = sum[ls] | sum[rs];
}
void build(int u, int l, int r) {
if (l == r) {
sum[u] = 1ll << a[pos[l]];
return;
}
int mid = l + r >> 1;
build(ls, l, mid);
build(rs, mid + 1, r);
pushup(u);
}
void pushdown(int u) {
if (lazy[u]) {
lazy[ls] = lazy[rs] = lazy[u];
sum[rs] = sum[ls] = 1ll << lazy[u];
lazy[u] = 0;
}
}
void modify(int u, int l, int r, int L, int R, int c) {
if (L <= l && r <= R) {
sum[u] = 1ll << c;
lazy[u] = c;
return;
}
int mid = l + r >> 1;
pushdown(u);
if (L <= mid) modify(ls, l, mid, L, R, c);
if (mid + 1 <= R) modify(rs, mid + 1, r, L, R, c);
pushup(u);
}
int query(int u, int l, int r, int L, int R) {
if (l >= L && r <= R) {
return sum[u];
}
pushdown(u);
int mid = l + r >> 1;
int val = 0;
if (L <= mid) val |= query(ls, l, mid, L, R);
if (R > mid) val |= query(rs, mid + 1, r, L, R);
pushup(u);
return val;
}
} tr;
int l[N], r[N], tot;
void dfs(int u, int fa) //dfs序
{
l[u] = ++tot;
pos[tot] = u;
for (auto v : g[u]) {
if (v == fa) continue;
dfs(v, u);
}
r[u] = tot;
}
int cnt(int val) //计算区间有多少种颜色即查询二进制位有多少个1
{
int ans = 0;
while (val) {
ans += val & 1;
val >>= 1;
}
return ans;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; ++i) cin >> a[i];
for (int i = 1; i < n; ++i) {
int a, b;
cin >> a >> b;
g[a].push_back(b);
g[b].push_back(a);
}
dfs(1, 0);
tr.build(1, 1, n);
while (m--) {
int op, x;
cin >> op >> x;
if (op == 1) {
int c;
cin >> c;
tr.modify(1, 1, n, l[x], r[x], c);
} else {
cout << cnt(tr.query(1, 1, n, l[x], r[x])) << endl;
}
}
return 0;
}
CF620E New Year Tree(树形+dfs序+线段树+状态压缩)的更多相关文章
- CodeForces 620E"New Year Tree"(DFS序+线段树+状态压缩)
传送门 •题意 给你一颗 n 个节点的树,每个节点被染上了颜色: 有 m 次操作,每次操作的类型有两种 1 v c : 将以 v 为根的子树的结点全部涂成 c 2 v : 询问以 v 为根的子树的结点 ...
- Codeforces 343D Water Tree(DFS序 + 线段树)
题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...
- 【cf343】D. Water Tree(dfs序+线段树)
传送门 题意: 给出一个以\(1\)为根的有根树,起始每个结点都为\(0\),现在有三种操作: 1.将\(v\)及\(v\)的子树都置为\(1\): 2.将\(v\)及其所有的祖先都置为\(0\): ...
- Codeforces 620E New Year Tree(DFS序 + 线段树)
题目大概说给一棵树,树上结点都有颜色(1到60),进行下面两个操作:把某结点为根的子树染成某一颜色.询问某结点为根的子树有多少种颜色. 子树,显然DFS序,把子树结点映射到连续的区间.而注意到颜色60 ...
- POJ3321/Apple tree/(DFS序+线段树)
题目链接 Apple Tree Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9692 Accepted: 3217 Descr ...
- CoderForces343D:Water Tree(dfs序+线段树&&特殊处理)
Mad scientist Mike has constructed a rooted tree, which consists of n vertices. Each vertex is a res ...
- POJ 3321 Apple Tree(DFS序+线段树单点修改区间查询)
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 25904 Accepted: 7682 Descr ...
- New Year Tree 【DFS序+线段树区间查询修改+二进制保存状态】
题目链接[http://codeforces.com/problemset/problem/620/E] 题意:给出n个数,每个数有一个初始的颜色.由这n个数组成一颗树.有两种操作1.将以节点u为根的 ...
- POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)
POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...
随机推荐
- WAF对抗-安全狗(联合查询篇)
WAF对抗-安全狗(联合查询篇) 实验环境 网站安全狗APACHE版V4.0.靶场:dvwa 为了方便对比可以在这个在线靶场申请一个dvwa https://www.vsplate.com/ mysq ...
- 写给前端的 react-native 入门指南
前言 本文主要介绍 react-native(下称 RN) 的入门, 和前端的异同点 文章不涉及功能的具体实现 选择优势 我们先说说, 为什么很多人会选择使用 RN .他对应的特性和普通 Web 的区 ...
- 实践分享!GitLab CI/CD 快速入门
用过 GitLab 的同学肯定也对 GitLab CI/CD 不陌生,GitLab CI/CD 是一个内置在 GitLab 中的工具,它可以帮助我们在每次代码推送时运行一系列脚本来构建.测试和验证代码 ...
- eBackup备份服务器安装及配置
####### 原博客地址 创建虚拟机 选择第一个 分配硬盘 其余默认 导入压缩包安装eBackup备份软件 用户名root 密码Cloud12#$ 查看ip地址 连接xftp导入包 安装备份软件 # ...
- 虚拟机里做LUN映射(RHEL系统和centos系统皆可)(Linux版)
紧接着Windows的LUN映射之后 参考 (https://www.cnblogs.com/zhengyan6/p/16121268.html) 先删除部分配置(没有做之前的LUN映射则不用) 进网 ...
- Job And Schedule (V8R6C4)
KingbaseES 数据库提供了 kdb_schedule 扩展,使得用户能通过类似oracle job 的方式进行job调用.kdb_schedule 提供了三个Schema :dbms_job ...
- 面试突击83:什么情况会导致@Transactional事务失效?
一个程序中不可能没有事务,而 Spring 中,事务的实现方式分为两种:编程式事务和声明式事务,又因为编程式事务实现相对麻烦,而声明式事务实现极其简单,所以在日常项目中,我们都会使用声明式事务 @Tr ...
- WSUS连接错误需要重置服务器
在WSUS完成部署后,总是遇到控制台错误,提示需要重置服务器节点.https://www.cnblogs.com/qishine/p/12727982.html错误:连接错误尝试连接WSUS服务器时出 ...
- 常用的清理 Kubernetes 集群资源命令
1. Kubernetes 基础对象清理 清理 Evicted 状态的 Pod kubectl get pods --all-namespaces -o wide | grep Evicted | a ...
- 示例:Service连接应用程序
整体思路: 1.创建pod 2.创建关联上一步pod的service 3.使用不同的方式配置service从而能够在集群内部访问 4.使用ssl方式加密访问service 5.配置service为no ...