码迷,mamicode.com
首页 > 其他好文 > 详细

Marked Ancestor [AOJ2170] [并查集]

时间:2018-06-25 22:48:37      阅读:208      评论:0      收藏:0      [点我收藏+]

标签:编号   first   index   include   tor   bsp   fir   closed   note   

题意:
有一个树,有些节点染色,每次有两种操作,第一,统计该节点到离它最近的染色父亲结点的的号码(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

分析:

这道题乍一看是一道在树上玩的图论/数据结构题?

但是我想半天都没想到有什么好一点的办法去做这道题。

根据作业专题:并查集,我们来思考如何靠近并查集。

显然并查集的功能是“并”,而这个题的要求显然是“拆”。

我们如果倒过来看,拆就变成并了,而很多拆的题目就是反过来处理使用并查集的。

那我们就把所有询问记录下来,并记录每个点被标记的最早时间。

那我们在查询父节点的时候,条件便是 当前点被标记的时间早于查询时间 ? 该点 :递归父节点(路径压缩)

我们是否担心路径压缩会出错?

不会,因为我们倒序后,压缩的是已经晚于查询节点的时间的,而我们的查询时间是不断向前走的。

代码:

 

技术分享图片
 1 #include<set>
 2 #include<map>
 3 #include<queue>
 4 #include<stack>
 5 #include<cmath>
 6 #include<cstdio>
 7 #include<cstring>
 8 #include<iostream>
 9 #include<algorithm>
10 #define RG register ll
11 #define rep(i,a,b)    for(RG i=a;i<=b;++i)
12 #define per(i,a,b)    for(RG i=a;i>=b;--i)
13 #define ll long long
14 #define inf (1<<29)
15 #define maxn 100005
16 using namespace std;
17 ll n,T,x,cnt,tim,ans;
18 ll fa[maxn],tag[maxn],qa[maxn],qb[maxn];
19 inline ll read()
20 {
21     ll x=0,f=1;char c=getchar();
22     while(c<0||c>9){if(c==-)f=-1;c=getchar();}
23     while(c>=0&&c<=9){x=x*10+c-0;c=getchar();}
24     return x*f;
25 }
26 
27 ll find(ll x)
28 {
29     return tag[x]<tim?x:fa[x]=find(fa[x]);
30 }
31 
32 int main()
33 {
34     while(1)
35     {
36         n=read(),T=read();
37         if(n==0&&T==0)    return 0;
38         ans=cnt=0;
39         rep(i,2,n)    fa[i]=read(),tag[i]=i+T;
40         char s[5];
41         rep(i,1,T)
42         {
43             scanf("%s",s);x=read();
44             if(s[0]==M)
45                 tag[x]=min(tag[x],i);
46             else
47                 qa[++cnt]=x,qb[cnt]=i;
48         }
49         per(i,cnt,1)
50         {
51             tim=qb[i];
52             ans+=find(qa[i]);
53         }
54         cout<<ans<<endl;
55     }
56     return 0;
57 }
View Code

Marked Ancestor [AOJ2170] [并查集]

标签:编号   first   index   include   tor   bsp   fir   closed   note   

原文地址:https://www.cnblogs.com/ibilllee/p/9226440.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!