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,对于任意两个 ...
随机推荐
- Centos7+ASP.Net Core 运行
一:ASP.Net Core跨平台运行,需要在Linux安装运行环境.本机器使用的Centos,下载安装地址为:https://www.microsoft.com/net/core#centos su ...
- 不显示TensorFlow加速指令警告
vim ~/.bashrc 在打开的文件中追加: export TF_CPP_MIN_LOG_LEVEL= 最后再执行 source ~/.bashrc
- [SDOI2018]原题识别
题解: ..感觉挺烦得 而且我都没有注意到树随机这件事情.. 就写个30分的莫队.. #include <bits/stdc++.h> using namespace std; #defi ...
- luogu P2742 【模板】二维凸包 / [USACO5.1]圈奶牛Fencing the Cows
题解: 二维凸包裸题 按照x坐标为第一关键字,y坐标为第二关键字排序 然后相邻判断叉积用单调队列搞过去 正反都做一次就好了 代码: #include <bits/stdc++.h> usi ...
- [转]利用ssh传输文件
利用ssh传输文件 http://www.cnblogs.com/jiangyao/archive/2011/01/26/1945570.html 在linux下一般用scp这个命令来通过ssh传输文 ...
- 创建和使用动态链接库(转)vs2008 vs2010
最近在用c++使用dll,找了好久,下面有个例子.我用的是vs2010,第二个验证过没有问题! vs2008http://wenku.baidu.com/view/e2f64a3b87c2402891 ...
- 构建简单的json树形菜单
json结构: var Menu = [{ tit:"一级菜单", submenu:[{ tit:"二级菜单", url:"", func: ...
- openstack2 kvm
一.kvm安装 1.首先虚拟机的话需要打开虚拟化功能,服务器的话需要在bios中设置 2.安装kvm用户态管理工具qemu-kvm 和 用来管理kvm虚拟机的插件libvirt和创建虚拟机用的virt ...
- BZOJ1396 识别子串 字符串 SAM 线段树
原文链接http://www.cnblogs.com/zhouzhendong/p/9004467.html 题目传送门 - BZOJ1396 题意 给定一个字符串$s$,$|s|\leq 10^5$ ...
- RocketMQ事务消息回查设计方案
用户U1从A银行系统转账给B银行系统的用户U2的处理过程如下:第一步:A银行系统生成一条转账消息,以事务消息的方式写入RocketMQ,此时B银行系统不可见这条消息(Prepare阶段) 第二步:写入 ...