Description

在2016年,佳媛姐姐刚刚学习了树,非常开心。现在他想解决这样一个问题:给定一颗有根树(根为1),有以下
两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均无标记,而且对于某个
结点,可以打多次标记。)2. 询问操作:询问某个结点最近的一个打了标记的祖先(这个结点本身也算自己的祖
先)你能帮帮他吗?

Solution

还是非常巧妙的思维

离线,先记录每个点的标记数,倒序处理询问,遇到打标记就把标记数减一,对于标记数为0的点就用并查集与它的父节点合并

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<vector>
#define MAXN 100005
using namespace std;
int n,q,head[MAXN],cnt=0,f[MAXN],father[MAXN],num[MAXN],sign[MAXN];
char opt[MAXN];
vector<int>v;
struct Node
{int next,to;
}Edges[MAXN*2];
void addedge(int u,int v)
{Edges[++cnt].next=head[u];head[u]=cnt;Edges[cnt].to=v;
}
int read()
{int x=0,f=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f;
}
int find(int x)
{if(father[x]==x)return x;return father[x]=find(father[x]);
}
void dfs(int u)
{if(!sign[u])father[u]=find(f[u]); for(int i=head[u];~i;i=Edges[i].next){int v=Edges[i].to;if(v==f[u])continue;f[v]=u;dfs(v);}
}
int main()
{memset(head,-1,sizeof(head));n=read(),q=read();for(int i=1;i<n;i++){int u=read(),v=read();addedge(u,v);addedge(v,u);father[i]=i;}father[n]=n,sign[1]++;for(int i=1;i<=q;i++){opt[i]=getchar();while(opt[i]!='Q'&&opt[i]!='C')opt[i]=getchar();num[i]=read();if(opt[i]=='C')sign[num[i]]++;}dfs(1);for(int i=q;i>0;i--){if(opt[i]=='C'){sign[num[i]]--;if(!sign[num[i]])father[num[i]]=find(f[num[i]]);}elsev.push_back(find(num[i]));}for(int i=v.size()-1;i>=0;i--)printf("%d\n",v[i]);return 0;
} 

转载于:https://www.cnblogs.com/Zars19/p/6872287.html

[BZOJ 4551][Tjoi2016Heoi2016]树(并查集)相关推荐

  1. bzoj 4551: [Tjoi2016Heoi2016]树【并查集】

    看起来像是并查集,但是是拆集合,考虑时间倒流,先把标记都打上,然后把并查集做出来 每次到一个修改点就把这个点的计数s[u]--,当这个s为0时就把这个点和他的父亲合并(因为可能有多次标记) #incl ...

  2. bzoj 4551[Tjoi2016Heoi2016]树

    这题可以用并查集做,一开始统计一下记录每个点被标记了几次,除了被标记过的点外,其他节点都与其父亲所在集合合并,然后倒着做,做的时候如果有节点标记次数变为了0,则将其与其父亲合并. 代码 1 #incl ...

  3. HDU 1512 Monkey King 左偏树 + 并查集

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1512 题意:有n个猴子,一开始每个猴子只认识自己.每个猴子有一个力量值,力量值越大表示这个猴子打架越厉害. ...

  4. 可持久化线段树【主席树】可持久化并查集【主席树+并查集】

    笼统的主席树原理 众所周知, 主席树是可以持久化的, 换言之你能知道你所维护信息的所有历史状态. 主席树是这样做的: 1. 首先建一颗朴素的线段树,代表初始状态 (下图黑色) , 也就是第0次操作后的 ...

  5. bzoj 36733674 可持久化并查集加强版(可持久化线段树+启发式合并)

    CCZ在2015年8月25日也就是初三暑假要结束的时候就已经能切这种题了%%% 学习了另一种启发式合并的方法,按秩合并,也就是按树的深度合并,实际上是和按树的大小一个道理,但是感觉(至少在这题上)更好 ...

  6. bzoj 2054: 疯狂的馒头(线段树||并查集)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2054 线段树写法: 点的颜色只取决于最后一次染的颜色,所以我们可以倒着维护,如果当前区间之前 ...

  7. bzoj 36733674: 可持久化并查集 by zky

    Description n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0& ...

  8. BZOJ 3673: 可持久化并查集 by zky

    Description n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0& ...

  9. POJ - 2513 Colored Sticks(字典树+并查集+欧拉回路)

    题目链接:点击查看 题目大意:给出n个木棍,问若两两相连,最终能否构成一根长直木棍,相连的规则是两个木棍的相接端点的颜色需要保持相同 题目分析:关于这个题目,我们可以将每个木棍视为一条边,每个木棍的两 ...

最新文章

  1. java包和继承的区别,子类和父类在同一个包中继承性
  2. 让机器“自愈化”引领新科技变革
  3. 使用MyEclipse创建可执行jar
  4. php中处理xml文件的类 simpleXML
  5. linux 挂载多余空间,linux 空间不够,磁盘挂载
  6. [css] 写一个动画,向上匀速移动100px,向下以1.5倍速度移动200px,一直反复循环
  7. 学习前端开发,自学真的能成功?
  8. 注册信息表html,实战系列 —— HTML 的 “注册信息表”
  9. linux进程名称最大长度,linux – 进程名称长度的最大允许限制是多少?
  10. 三角形外心的坐标公式
  11. NiceScroll接管iview table高度自适应变化
  12. 【ANSYS命令流】定义单元类型与实常数
  13. 在云服务器上搭建Kali系统-最新kali2021.3版本+避坑指南
  14. caesar java_java实现caesar加解密算法
  15. 学习使用linux下tags文件
  16. 疯狂原始人手游怎么用电脑玩 疯狂原始人手游PC电脑版教程
  17. 转换IC CD7833CZ:4x41W汽车音响功率放大电路
  18. java让线程空转_详解Java编程中对线程的中断处理
  19. 卷积神经网络(CNN)开山之作——LeNet-5。卷积神经网络基本介绍。
  20. 在外卖平台也能当主播,美团直播到底“行不行”?

热门文章

  1. 基于netty实现mq
  2. php 文件夹里有多少,计算目录php中有多少个文件
  3. sql怎么把小数变百分比_云计算基本技能有哪些 怎么监控Linux系统内存
  4. c 输出空格_Python编程:案例详解输出函数print
  5. android studio差异化,productFlavors + buildTypes + signingConfigs 构建差异化 Android 应用
  6. Python 统计列表中元素出现的次数
  7. pci规划的三个原则_NR PCI规划
  8. 数据结构实验之串三:KMP应用
  9. 【C++】20. const char *str[]、指针的字节长度等 分析
  10. 打造高效的工作环境 – SHELL 篇