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,对于任意两个 ...
随机推荐
- jquery实现全选 反选 取消
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- cmake方式使用vlfeat
目录 environment statement compile vlfeat with cmake compile example project with cmake 1. make sure c ...
- 记录sql server中数据创建时间和最后修改时间,方便查找问题
getdate()用例: 2008-12-29 16:25:46.635 1.创建时间:将字段设置为datetime类型,并设置默认值为 getdate() 2.修改时间:通过触发器,在 update ...
- JavaScript学习:取数组中最大值和最小值
在实际业务中有的时候要取出数组中的最大值或最小值.但在数组中并没有提供arr.max()和arr.min()这样的方法.那么是不是可以通过别的方式实现类似这样的方法呢?那么今天我们就来整理取出数组中最 ...
- TURN TAP: Temporal Unit Regression Network for Temporal Action Proposals(ICCV2017)
Motivation 实现快速和准确地抽取出视频中的语义片段 Proposed Method -提出了TURN模型预测proposal并用temporal coordinate regression来 ...
- [转]Spring Boot修改最大上传文件限制:The field file exceeds its maximum permitted size of 1048576 bytes.
来源:http://blog.csdn.net/awmw74520/article/details/70230591 SpringBoot做文件上传时出现了The field file exceeds ...
- Elasticsearch - Scroll
Scroll Version:6.1 英文原文地址:Scroll 当一个搜索请求返回单页结果时,可以使用 scroll API 检索体积大量(甚至全部)结果,这和在传统数据库中使用游标的方式非常相似. ...
- windows server远程连接提示“终端服务器超出了最大允许连接”
- iframe获取元素
原生js在网页中,父元素获取iframe中的元素: window.onload=function () { 例如: console.log(window.frames["iframe的nam ...
- jquery的div局部刷新
jquery的div局部刷新 //div的局部刷新 $(".dl").load(location.href+" .dl"); 全页面的刷新方法 window.l ...