有关dfs序的例题,需要有一定的位运算基础

题面

  • 给定一个树,树上有颜色,将某一子树的颜色统一修改,求子树中颜色的数量

Solution

  • 子树修改,子树求和,dfs序的知识(类似区间修改区间求和)
  • 考虑到颜色的个数问题,利用位运算进行表示。
  • 最后答案用二进制表示,\(\ 1\)表示有该种颜色,\(\ 0\)表示没有,
  • 因此还需考虑答案\(\ 1\)的数量。
  • dfs序问题自然用到线段树进行维护。

具体介绍一下位运算,和一些小错误

  • 方案总数不是两个节点维护的方案数的简单相加,而是“|”(或)
  • 答案维护的是颜色的个数,但不是具体数值
  • 关于答案\(\ 1\)的个数,可以利用快速幂
  • 也可利用\(\ lowbit\),作用是得到最后\(\ 1\)的位置上表示的数。
  • 建树的时候特别记住需要\(\ long \ long\)的地方

    更加详细的内容

Code

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int manx=1e6+10;
const int mamx = 1e7 + 11;
const int B = 1e6 + 11;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
inline int read() {
char c = getchar(); int x = 0, f = 1;
for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1;
for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
return x * f;
}
struct nodee{
int l,r;
ll sum;
ll add;
}e[manx<<2+2];
int clr[manx<<1];
struct node{
int u;
int v;
int nxt;
int w;
}ee[manx];
int head[manx],js,l[manx],r[manx],cnt,n,m,dfn[manx];
int add(int u,int v){
ee[++cnt].u = u;
ee[cnt].nxt = head[u];
ee[cnt].v = v;
//e[cnt].w = w;
head[u] = cnt;
}
inline void init(){
cnt=js=0;
clr(head,-1);
}
//大法师
void dfs(int u, int pre){
js++;
l[u] = js;
dfn[js] = u;
for(int i = head[u];~i;i = ee[i].nxt){
int v = ee[i].v;
if( v == pre ) continue;
dfs(v,u);
}
r[u] = js; //我们可以只记录他的入段,尾端那个不必重复
return ;
}
//线段树
void uploat(int s){//上传
e[s].sum = 0;
if(e[s<<1].l) e[s].sum |=e[s<<1].sum ;
if(e[s<<1|1].l ) e[s].sum |=e[s<<1|1].sum ;
}
void downloat(int i){
if(e[i].add !=0){
ll s = e[i].add ;//不要用int 用ll,作者就在这卡了一天
e[i<<1].sum = s;
e[i<<1].add = s;
e[i<<1|1].add = s;
e[i<<1|1].sum = s;
e[i].add = 0;
}
}
void build_up (int rt,int l,int r){
e[rt].l = l;e[rt].r = r;
if(l == r){
e[rt].sum = (ll)1<<(clr[dfn[l]]);
e[rt].add = 0;
return;
}
int mid = (l+r) >> 1;
build_up(rt<<1,l,mid);
build_up(rt<<1|1,mid+1,r);
e[rt].sum = e[rt<<1].sum | e[rt<<1|1].sum;
}
void updata(int i,int l,int r,int add){
if(e[i].l >= l && e[i].r <= r)
{
e[i].sum = (ll)1<<add;
e[i].add = (ll)1<<add;
return;
}
int mid = (e[i].l + e[i].r ) >> 1;
downloat(i);
if(mid >= r)updata(i<<1,l,r,add);
else if(mid <l)updata(i<<1|1,l,r,add);
else updata(i<<1,l,mid,add),updata(i<<1|1,mid+1,r,add);
uploat(i);
}
ll query(int i,int l,int r)
{
if(e[i].l >= l && e[i].r <= r){
return e[i].sum ;
}
downloat(i);
int mid = (e[i].l +e[i].r ) >> 1;
if(mid >= r)
return query(i<<1,l,r);
else
if(mid<l)
return query(i<<1|1,l,r);//熟悉的操作
return query(i<<1,l,mid)|query(i<<1|1,mid+1,r);
}
ll lowbit(ll x){
return x&-x;//lowbit函数
}
int ans;
int main(){
n = read();
m = read();
init ();
for(int i = 1;i <= n;i ++)
clr[i] = read();
for(int i = 1;i <= n - 1;i ++)
{
int x = read(),y = read();
add(x,y);add(y,x);
}
dfs(1,0);
build_up(1,1,n);//建树
for(int i = 1;i <= m; i++)
{
int x = read();
int y;
int z;
if(x == 1){
y = read();z = read();
updata(1,l[y],r[y],z);
}
else{
ans = 0;y = read();
ll diet = query(1,l[y],r[y]);
while(diet>0){
diet-=lowbit(diet);
ans++;//判断1的个数
}
cout<<ans<<endl;//华丽收场
}
}
return 0;
}

题解 CF620E 【New Year Tree】的更多相关文章

  1. 题解:CF593D Happy Tree Party

    题解:CF593D Happy Tree Party Description Bogdan has a birthday today and mom gave him a tree consistin ...

  2. CF620E New Year Tree(线段树+二进制)

    题解 弱智题,二进制表示位数.合并时用| 就是被1<<x卡了好久. 要写成1ll<<x才行 #include<iostream> #include<cstri ...

  3. 题解-CF429C Guess the Tree

    题面 CF429C Guess the Tree 给一个长度为 \(n\) 的数组 \(a_i\),问是否有一棵树,每个节点要么是叶子要么至少有两个儿子,而且 \(i\) 号点的子树大小是 \(a_i ...

  4. 题解-AtCoder Code-Festival2017 Final-J Tree MST

    Problem \(\mathrm{Code~Festival~2017~Final~J}\) 题意概要:一棵 \(n\) 个节点有点权边权的树.构建一张完全图,对于任意一对点 \((x,y)\),连 ...

  5. PAT甲题题解-1110. Complete Binary Tree (25)-(判断是否为完全二叉树)

    题意:判断一个节点为n的二叉树是否为完全二叉树.Yes输出完全二叉树的最后一个节点,No输出根节点. 建树,然后分别将该树与节点树为n的二叉树相比较,统计对应的节点个数,如果为n,则为完全二叉树,否则 ...

  6. [LeetCode 题解]: Validate Binary Search Tree

    Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as ...

  7. [CF620E]New Year Tree

    题目大意:有一棵以$1$为根的有根树,有$n$个点,每个节点初始有颜色$c_i$.有两种操作: $1 v c:$将以$v$为根的子树中所有点颜色更改为$c$ $2 v:$ 查询以$v$为根的子树中的节 ...

  8. leetcode题解:Construct Binary Tree from Inorder and Postorder Traversal(根据中序和后序遍历构造二叉树)

    题目: Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume ...

  9. 题解 CF383C 【Propagating tree】

    这道题明明没有省选难度啊,为什么就成紫题了QAQ 另:在CF上A了但是洛谷Remote Judge玄学爆零. 思路是DFS序+线段树. 首先这道题直观上可以对于每一次修改用DFS暴力O(n),然后对于 ...

随机推荐

  1. 常见数据库的JDBC URL

    转自:http://blog.csdn.net/ring0hx/article/details/6152528 Microsoft SQL Server Microsoft SQL Server JD ...

  2. 如何在Nginx不绑定域名下使用SSL/TLS证书?

    前提 该文主要记录如何在没有购买域名的情况下使用SSL/TLS协议,即地址前面的http变成了https.但是这样的SSL协议是会被浏览器认为是不安全的.在开发或者测试环境可以这样搞,生产环境下还是乖 ...

  3. TurtleBot3 Waffle (tx2版华夫)(5)激活你的雷达

    重要提示:请在配网通信成功后进行操作,配网后再次开机需要重新验证通信: 重要提示:[Remote PC]代表PC端.[TurtelBot]代表树莓派端: 5.1.操作步骤 1)[Remote PC]  ...

  4. Beta冲刺——第七天

    这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzzcxy/2018SE1 这个作业要求在哪里 https://edu.cnblogs.com/campus/fz ...

  5. netcore项目中使用 SpringCloudConfig 和apollo做配置中心

    版权所有,转载请注明出处 https://www.cnblogs.com/netqq/p/14251403.html 一.使用apollo作为配置中心 首先apollo 项目简介和安装请自行百度,本文 ...

  6. NOIP初赛篇——02计算机系统的基本结构

    引言 计算机系统由硬件和软件两部分组成,硬件系统是计算机的"躯干",是物质基础.而软件系统则是建立在这个"躯干"上的"灵魂". 计算机硬件 ...

  7. FastApi学习(二)

    前言 继续学习 此为第二篇, 还差些知识点就可以结束, 更多的比如用户的身份校验/ swagger 文档修改等以后会单独写 正文 使用枚举来限定参数 可以使用枚举的方式来限定参数为某几个值之内才通过 ...

  8. 服务器报错"您的主机中的软件中止了一个已建立的连接"

    网上很多的说法都模棱两可,只是说和远程连接有关,这个说的太泛泛了. 我现在遇到的问题是java web出现的, 执行表单提交的时候出现该错误,原因是ajax和表单同时提交导致的, 相信很多朋友用了aj ...

  9. 最全的HashMap源码解析!

    HashMap源码解析 HashMap采用键值对形式的存储结构,每个key对应唯一的value,查询和修改的速度很快,能到到O(1)的平均复杂度.他是非线程安全的,且不能保证元素的存储顺序. 他的关系 ...

  10. .NET斗鱼直播弹幕客户端(2021)

    .NET斗鱼直播弹幕客户端(2021) 离之前更新的两篇<.NET斗鱼直播弹幕客户端>已经有一段时间,近期有许多客户向我反馈刚好有这方面的需求,但之前的代码不能用了--但网上许多流传的No ...