[POJ 1988] Cube Stacking (带值的并查集)
题目链接:http://poj.org/problem?id=1988
题目大意:给你N个方块,编号从1到N,有两种操作,第一种是M(x,y),意思是将x所在的堆放到y所在的堆上面。 第二种是C(x),意思是数x方块下面有多少个方块。
把两堆合成一堆,这个可以用并查集来实现,问题是,怎么样维护x方块下面有多少个方块呢?
先来分析一下题目,按照样例,我们有6个方块,1,2,3,4,5,6。
令Cnt(x) = C(x)+1。
先执行M(1,6),此时Cnt(1) = 2, Cnt(6) = 1
再执行M(2,4),此时Cnt(2) = 2, Cnt(4) = 1
接下来我们执行M(2,6),此时Cnt(2) = 4, Cnt(4) = 3。
注意到了没有,意思也就是说我们给2和4每一个都增加了Cnt(1)
我们可以利用类似线段树的懒惰标记思想,给方块2加上2点“懒惰值”,然后需要读取4的值的时候,我们再把它统计进来。
由于并查集记录的是父亲节点,因此我们需要把树反着来,也就是说,2摞在6上面,在并查集中,6是2的父亲。
代码:
#include <cstdio>
#include <algorithm>
#include <bitset>
#include <set>
#include <vector>
#include <iterator>
#include <cstring>
#include <map>
#include <cctype>
using namespace std; const int MAX_N = +;
int f[MAX_N],lazy[MAX_N],sum[MAX_N]; void init(){
for(int i=;i<=MAX_N;i++){
f[i] = i;
lazy[i] = ;
sum[i] = ;
}
} int find(int x){
if( f[x] == x ) return x;
int t = find(f[x]);
lazy[x] += lazy[f[x]];
return f[x] = t;
} void merge(int x,int y){
int fx = find(x) , fy = find(y);
if( fx==fy ) return;
lazy[fx]+=sum[fy];
sum[fy]+=sum[fx];
sum[fx] = ;
f[fx] = fy;
} int main(){
int P,X,Y;
char cmd[];
scanf("%d",&P);
init();
while(scanf("%s",cmd)!=EOF){
if( cmd[]=='M' ) {
scanf("%d%d",&X,&Y);
merge(X,Y);
} else {
scanf("%d",&X);
find(X);
printf("%d\n",lazy[X]);
}
// for(int i=1;i<=P;i++){
// printf("lazy[%d]=%d, sum[%d]=%d\n",i,lazy[i],i,sum[i]);
// }
} return ;
}
[POJ 1988] Cube Stacking (带值的并查集)的更多相关文章
- POJ 1988 Cube Stacking(带权并查集)
哈哈,一次AC. 题意:给你 1-n 编号的立方体,然后移动包含指定编号的立方体的堆移到另一个堆上边, 询问指定的编号立方体下面有多少个立方体. 思路:由于并查集是存储的是它的父亲,那么只能从父亲那里 ...
- POJ 1988 Cube Stacking( 带权并查集 )*
POJ 1988 Cube Stacking( 带权并查集 ) 非常棒的一道题!借鉴"找回失去的"博客 链接:传送门 题意: P次查询,每次查询有两种: M x y 将包含x的集合 ...
- POJ 1988 Cube Stacking(并查集+路径压缩)
题目链接:id=1988">POJ 1988 Cube Stacking 并查集的题目 [题目大意] 有n个元素,開始每一个元素自己 一栈.有两种操作,将含有元素x的栈放在含有y的栈的 ...
- POJ 1988 Cube Stacking(带权并查集)
Cube Stacking Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 23678 Accepted: 8299 Ca ...
- POJ 1988 Cube Stacking 【带权并查集】
<题目链接> 题目大意: 有几个stack,初始里面有一个cube.支持两种操作: 1.move x y: 将x所在的stack移动到y所在stack的顶部. 2.count x:数在x所 ...
- poj.1988.Cube Stacking(并查集)
Cube Stacking Time Limit:2000MS Memory Limit:30000KB 64bit IO Format:%I64d & %I64u Submi ...
- POJ 1988 Cube Stacking (种类并查集)
题目地址:POJ 1988 这道题的查找合并的方法都能想的到,就是一点没想到,我一直天真的以为查询的时候,输入后能立即输出,这种话在合并的时候就要所有的结点值都要算出来,可是经过路径压缩之后,没办法所 ...
- POJ 1988 Cube stacking【并查集高级应用+妙用deep数组】
Description Farmer John and Betsy are playing a game with N (1 <= N <= 30,000)identical cubes ...
- poj 1182 食物链 (带关系的并查集)
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 44835 Accepted: 13069 Description 动 ...
随机推荐
- 1362. Classmates 2
http://acm.timus.ru/problem.aspx?space=1&num=1362 水题,树形DP 代码: #include<iostream> #include& ...
- 手机抓包-fiddler
如果app走的是http协议,不用root,只需要通过fiddler做代理,就可以抓到所有请求. 1. fiddler+手机wifi设置 安装fiddler,勾中 Fiddler Options -& ...
- 转 Flex MXML编译成AS类
2009-09-22 23:25 Flex MXML编译成AS类 由“Flex 基础”文中可知:每一个mxml文件首先要编译成as文件,然后再译成swf文件.app.mxml文件编译后会产生一系列中间 ...
- oracle 拼接一张表所有字段
declare t_name varchar2(100) := upper('dba_tab_columns'); cursor c_col is select column_name from db ...
- (转)JAVA实现Windows拨号、IP切换
原理: 通过调用windows下的dos命令实现拨号 PS:连接名称获取不一定都是适用,但苦于知道的dos命令太少了,只能将就这么用着. 如有更好的方法,烦请不吝赐教. public class Co ...
- IOS 瀑布流
本篇博客应该算的上CollectionView的高级应用了,从iOS开发之窥探UICollectionViewController(一)到今天的(五),可谓是由浅入深的窥探了一下UICollectio ...
- 关于Oracle10G在库内导数据时,用到的更新语句----ZT
两种方法: -- 方法1. UPDATE 表2 SET 表2.C = (SELECT B FROM 表1 WHERE 表1.A = 表2.A) WHERE EXIST ...
- MYSQL数据库操作语句
1.创建数据库 CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name [create_specification [, create_specifica ...
- iOS获取设备信息
NSString *strName = [[UIDevice currentDevice] name]; // Name of the phone as named by user ...
- qt5.4 msvc2013_64安装 目标计算机不匹配问题
本文主要解决一个问题:即在安装完成之后如下目标计算机不匹配问题. ------------------------------------------------------------------ ...