【CF620E】New Year Tree
(题面来自luogu)
题意翻译
你有一棵以1为根的有根树,有n个点,每个节点初始有一个颜色c[i]。
有两种操作:
1 v c 将以v为根的子树中所有点颜色更改为c
2 v 查询以v为根的子树中的节点有多少种不同的颜色
翻译贡献者UID:28455
n、m <= 4e5,ci <= 60。
今天唯一听懂的一道题目,调了两个小时……因为要查询子树信息,考虑构造出dfs序之后,用线段树维护区间颜色。因为颜色只有60种,可以维护在节点上维护bitset或者一个64位整型来压缩状态,每一位上表示以该点为根的子树内是否含有这个颜色。
线段树内的tag是不可以累加的,每个tag都是一次直接修改,因此要在下推时特判掉空的无效标记。
代码:
- #include <bitset>
- #include <cstdio>
- #include <iostream>
- #define maxn 400010
- using namespace std;
- template <typename T>
- void read(T &x) {
- x = 0;
- int f = 1;
- char ch = getchar();
- while (!isdigit(ch)) {
- if (ch == '-')
- f = -1;
- ch = getchar();
- }
- while (isdigit(ch)) {
- x = x * 10 + (ch ^ 48);
- ch = getchar();
- }
- x *= f;
- return;
- }
- int n, m;
- struct E {
- int to, nxt;
- } edge[maxn << 1];
- int head[maxn], top;
- inline void insert(int u, int v) {
- edge[++top] = (E) {v, head[u]};
- head[u] = top;
- }
- int color[maxn], val[maxn], dfn[maxn], size[maxn], tmr;
- void dfs(int u, int pre) {
- dfn[u] = ++tmr;
- size[u] = 1;
- val[tmr] = color[u];
- for (int i = head[u]; i; i = edge[i].nxt) {
- int v = edge[i].to;
- if (v != pre) {
- dfs(v, u);
- size[u] += size[v];
- }
- }
- }
- namespace Segment_tree {
- #define lc (nd<<1)
- #define rc ((nd<<1)|1)
- #define mid ((l + r) >> 1)
- bitset<61> seg[maxn << 2];
- bitset<61> tag[maxn << 2];
- inline void put_tag(int nd, bitset<61> op) {
- if (op.count()) //关键,以及第一个调炸的点
- seg[nd] = op,
- tag[nd] = op;
- }
- inline void push_down(int nd) {
- put_tag(lc, tag[nd]);
- put_tag(rc, tag[nd]);
- tag[nd].reset();//第二个调炸的点:忘记清除标记
- }
- inline void update(int nd) {
- seg[nd] = seg[lc] | seg[rc];
- }
- void build(int nd, int l, int r) {
- if (l == r) {
- seg[nd].set(val[l], 1);
- return;
- }
- build(lc, l, mid);
- build(rc, mid + 1, r);
- update(nd);
- }
- void modify(int nd, int l, int r, int ql, int qr, bitset<61> op) {
- if (l >= ql && r <= qr) {
- put_tag(nd, op);
- return;
- } else if (l > qr || r < ql)
- return;
- push_down(nd);
- modify(lc, l, mid, ql, qr, op);
- modify(rc, mid + 1, r, ql, qr, op);
- update(nd);
- }
- bitset<61> query(int nd, int l, int r, int ql, int qr) {
- if (l >= ql && r <= qr)
- return seg[nd];
- if (l > qr || r < ql) {
- bitset<61> t;
- return t;
- }
- push_down(nd);
- return query(lc, l, mid, ql, qr) | query(rc, mid + 1, r, ql, qr);
- }
- } using namespace Segment_tree;
- int main() {
- read(n), read(m);
- for (int i = 1; i <= n; ++i)
- read(color[i]);
- int u, v, t, k;
- for (int i = 1; i < n; ++i) {
- read(u), read(v);
- insert(u, v), insert(v, u);
- }
- dfs(1, 0);
- build(1, 1, n);
- bitset<61> op;
- for (int i = 1; i <= m; ++i) {
- read(t), read(v);
- if (t == 1) {
- read(k);
- op.reset();
- op.set(k, 1);
- modify(1, 1, n, dfn[v], dfn[v] + size[v] - 1, op);
- } else {
- op = query(1, 1, n, dfn[v], dfn[v] + size[v] - 1);
- printf("%d\n", op.count());
- }
- }
- return 0;
- }
【CF620E】New Year Tree的更多相关文章
- 线段树+Dfs序【CF620E】New Year Tree
Description 你有一棵以1为根的有根树,有n个点,每个节点初始有一个颜色c[i]. 有两种操作: 1 v c 将以v为根的子树中所有点颜色更改为c 2 v 查询以v为根的子树中的节点有多少种 ...
- 【数据结构】B-Tree, B+Tree, B*树介绍 转
[数据结构]B-Tree, B+Tree, B*树介绍 [摘要] 最近在看Mysql的存储引擎中索引的优化,神马是索引,支持啥索引.全是浮云,目前Mysql的MyISAM和InnoDB都支持B-Tre ...
- P3690 【模板】Link Cut Tree (动态树)
P3690 [模板]Link Cut Tree (动态树) 认父不认子的lct 注意:不 要 把 $fa[x]$和$nrt(x)$ 混 在 一 起 ! #include<cstdio> v ...
- LG3690 【模板】Link Cut Tree (动态树)
题意 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y是联通的 ...
- AC日记——【模板】Link Cut Tree 洛谷 P3690
[模板]Link Cut Tree 思路: LCT模板: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 30 ...
- LG3690 【模板】Link Cut Tree 和 SDOI2008 洞穴勘测
UPD:更新了写法. [模板]Link Cut Tree 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 后接两个整数(x,y),代表询问从x到y ...
- (RE) luogu P3690 【模板】Link Cut Tree
二次联通门 : luogu P3690 [模板]Link Cut Tree 莫名RE第8个点....如果有dalao帮忙查错的话万分感激 #include <cstdio> #includ ...
- LuoguP3690 【模板】Link Cut Tree (动态树) LCT模板
P3690 [模板]Link Cut Tree (动态树) 题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两 ...
- 【LeetCode】199. Binary Tree Right Side View 解题报告(Python)
[LeetCode]199. Binary Tree Right Side View 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/probl ...
随机推荐
- scrapy和scrapy-redis 详解一 入门demo及内容解析
架构及简介 Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应用框架,用途非常广泛. Scrapy 使用了 Twisted(其主要对手是Tornado)异步网络框架来处理 ...
- css-设置背景透明度
实现透明的css方法通常有以下3种方式,以下是不透明度都为80%的写法: css3的opacity:x,x 的取值从 0 到 1,如opacity: 0.8 兼容性:IE6.7.8不支持,IE9及以上 ...
- Python爬虫urllib模块
Python爬虫练习(urllib模块) 关注公众号"轻松学编程"了解更多. 1.获取百度首页数据 流程:a.设置请求地址 b.设置请求时间 c.获取响应(对响应进行解码) ''' ...
- 微信小程序——【百景游戏小攻略】
微信小程序--[百景游戏小攻略] 本次课程小项目中的图片以及文章还未获得授权!请勿商用!未经授权,请勿转载! 博客班级 https://edu.cnblogs.com/campus/zjcsxy/SE ...
- 【Android Studio】安卓开发初体验1——安装与试用
安装 (安装预留硬盘(C盘)空余空间16G以上,8G以上内存) Intel用户: 安装Android Studio和AVD(安卓虚拟机 Android Virtual Device) 安装过程需要注意 ...
- 什么是4G模块 4G模块的工作原理及特点
什么是4G模块 4G模块,也被叫做4G通信模块或4G DTU模块,他是物联网行业具有4G通信功能的一种产品,通过4G模块,我们可以实现工业设备数据通过无线4G网络传输到远端控制中心,并从控制中心通过4 ...
- C++函数四( 具有默认参数值的函数)
在C++语言中,可以设置函数形参的默认值,在调用函数时,若明确给出了实参的值,则使用相应实参的值;若没有给出相应实参的值,则使用默认的值.这将为函数调用带来方便和灵活. [示例] #include&l ...
- 9个JavaScript日常开发小技巧
1.生成指定范围的数字 在某些情况下,我们会创建一个处在两个数之间的数组.假设我们要判断某人的生日是否在某个范围的年份内,那么下面是实现它的一个很简单的方法 1 2 3 4 5 6 let start ...
- mysql char varchar
摘自:http://dev.mysql.com/doc/refman/5.6/en/char.html In contrast to CHAR, VARCHAR values are stored a ...
- 关于情感分类(Sentiment Classification)的文献整理
最近对NLP中情感分类子方向的研究有些兴趣,在此整理下个人阅读的笔记(持续更新中): 1. Thumbs up? Sentiment classification using machine lear ...