Marked Ancestor [AOJ2170] [并查集]
题意:
有一个树,有些节点染色,每次有两种操作,第一,统计该节点到离它最近的染色父亲结点的的号码(Q),第二,为某一个节点染色(M),求第一种操作和。
输入:
输入由多个数据集组成。每个数据集都有以下格式:
输入的第一行包含两个整数N和Q,分别表示树T中的节点数和操作数。这些数字满足以下条件:1≤N≤100000和1≤Q≤100000。
下面的N-1行,每行包含一个整数pi(i = 2,...,N),它表示第i个节点的父节点的编号。
接下来的Q行按顺序包含操作。每个操作都格式化为“M v”或“Q v”,其中v是节点的编号。
样例:
6 3
1
1
2
3
3
Q 5
M 3
Q 5
0 0
样例输出:
4
分析:
这道题乍一看是一道在树上玩的图论/数据结构题?
但是我想半天都没想到有什么好一点的办法去做这道题。
根据作业专题:并查集,我们来思考如何靠近并查集。
显然并查集的功能是“并”,而这个题的要求显然是“拆”。
我们如果倒过来看,拆就变成并了,而很多拆的题目就是反过来处理使用并查集的。
那我们就把所有询问记录下来,并记录每个点被标记的最早时间。
那我们在查询父节点的时候,条件便是 当前点被标记的时间早于查询时间 ? 该点 :递归父节点(路径压缩)
我们是否担心路径压缩会出错?
不会,因为我们倒序后,压缩的是已经晚于查询节点的时间的,而我们的查询时间是不断向前走的。
代码:
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define RG register ll
#define rep(i,a,b) for(RG i=a;i<=b;++i)
#define per(i,a,b) for(RG i=a;i>=b;--i)
#define ll long long
#define inf (1<<29)
#define maxn 100005
using namespace std;
ll n,T,x,cnt,tim,ans;
ll fa[maxn],tag[maxn],qa[maxn],qb[maxn];
inline ll read()
{
ll x=,f=;char c=getchar();
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} ll find(ll x)
{
return tag[x]<tim?x:fa[x]=find(fa[x]);
} int main()
{
while()
{
n=read(),T=read();
if(n==&&T==) return ;
ans=cnt=;
rep(i,,n) fa[i]=read(),tag[i]=i+T;
char s[];
rep(i,,T)
{
scanf("%s",s);x=read();
if(s[]=='M')
tag[x]=min(tag[x],i);
else
qa[++cnt]=x,qb[cnt]=i;
}
per(i,cnt,)
{
tim=qb[i];
ans+=find(qa[i]);
}
cout<<ans<<endl;
}
return ;
}
Marked Ancestor [AOJ2170] [并查集]的更多相关文章
- Aizu2170 Marked Ancestor(并查集)
https://vjudge.net/problem/Aizu-2170 并查集用于管理元素分组情况. 建树pre[]记录父节点,一开始只有结点1被标记了,所以find()最终得到的根都是1. 如果遇 ...
- Aizu 2170 Marked Ancestor(并查集变形)
寻找根节点很容易让人联想到DisjointSet,但是DisjointSet只有合并操作, 所以询问离线倒着考虑,标记会一个一个消除,这时候就变成合并了. 因为询问和查询的时间以及标记生效的时间有关, ...
- AOJ 2170 Marked Ancestor (基础并查集)
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=45522 给定一棵树的n个节点,每个节点标号在1到n之间,1是树的根节点,有如 ...
- AOJ 2170 Marked Ancestor[并查集][离线]
题意: 给你一颗N个节点的树,节点编号1到N.1总是节点的根.现在有两种操作: M v: 标记节点v Q v: 求出离v最近的标记的相邻节点.根节点一开始就标记好了. 现在给一系列操作,求出所有Q操作 ...
- 《挑战程序设计竞赛》2.4 数据结构-并查集 POJ1182 2236 1703 AOJ2170
POJ1182 http://poj.org/problem?id=1182 题目 难得的中文题... 食物链 Time Limit: 1000MS Memory Limit: 10000K Tota ...
- zoj3261 并查集离线处理
Connections in Galaxy War Time Limit:3000MS Memory Limit:32768KB 64bit IO Format:%lld & ...
- HDU1198水管并查集Farm Irrigation
Benny has a spacious farm land to irrigate. The farm land is a rectangle, and is divided into a lot ...
- HDOJ并查集题目 HDOJ 1213 HDOJ 1242
Problem Description Today is Ignatius' birthday. He invites a lot of friends. Now it's dinner time. ...
- LCA(最近公共祖先)离线算法Tarjan+并查集
本文来自:http://www.cnblogs.com/Findxiaoxun/p/3428516.html 写得很好,一看就懂了. 在这里就复制了一份. LCA问题: 给出一棵有根树T,对于任意两个 ...
随机推荐
- 20165328 预备作业3 Linux安装及命令
Linux安装及学习 Linux安装遇到的问题: 问题:在我开始安装虚拟机的时候,在安装过程中总会出现初始界面,且无法跳过,陷入死循环. 解决方法:我在网上百度搜索该问题之后得到了答案,第一个界面是要 ...
- Django_Admin操作
Django_Admin 创建Django_Admin 管理账户 D:\github\Django_Aadmin>python manage.py createsuperuser Usernam ...
- MyBatis - 8.MyBatis工作原理
Mybatis 配置 1.SQLSessionFactory的初始化 根据配置文件获取 SqlSessionFactory 2.openSession获取SqlSession对象 3.getMappe ...
- ionic 3 build后图片无法显示
运行命令 ionic cordova build android 生成了android-debug.apk. /home/han/project/zero_app/platforms/android/ ...
- 有关centos7 图形化root用户登录
好久不用的虚拟机开机后,是图形化登录界面,原来是命令行界面,后来安装和图形化 结果使用我记录的root密码死活登录不了,心想是不是时间久了忘记了root密码 然后开始尝试各种单用户修改root密码,再 ...
- Storm——Android SQLite数据库管理类库
Storm是一个Android SQLite数据库管理类库,可以通过注解创建表和迁移数据库.它不是ORM框架. 特性: 1.通过@Annotations创建表: 2.通过@Annotations迁 ...
- Python学习(五) —— 文件操作
一.文件操作 1.文件操作:数据持久化的一种 步骤:找到文件,打开文件,操作:读.写.追写,关闭文件 打开文件:f = open(文件路径,操作模式,编码方式),f:文件句柄.文件 ...
- log4j.xml 报告集成
等级: trace< debug<info<warn<error<fatal trace 追踪 deug: eclipse, Log4j配置 [1]从零开始 a). ...
- 修改注册表.exe的文件目录
文件打开方式不能选择默认打开文件 cmd >regedit 以sublime_text为例 HKEY_CLASSES_ROOT/Applications/sublime_text.exe/she ...
- 041 SparkSql的回顾与复习
在前面学完了SparkCore后,又学了SparkSQL,在继续加深学习之前,一定的复习还是很重要的.这里大体写一下,加深自己对SparlSQL的理解. 1.SparkSQL 首先是SaprkSQL与 ...