算是挺基础的东西

Description

    约翰和贝茜在玩一个方块游戏.编号为1到n的n(1≤n≤30000)个方块正放在地上.每个构成一个立方柱.
   游戏开始后,约翰会给贝茜发出P(1≤P≤100000)个指令.指令有两种:
    1.移动(M):将包含X的立方柱移动到包含Y的立方柱上.
    2.统计(C):统计名含X的立方柱中,在X下方的方块数目.
    写个程序帮贝茜完成游戏.

Input

    第1行输入P,之后P行每行输入一条指令.形式为“M X Y”或者“C X”
    输入保证不会有将立方柱放在自己头上的指令.

Output

    每一行,对于每个统计指令,输出其结果.

Sample Input

6
M 1 6
C 1
M 2 4
M 2 6
C 3
C 4

Sample Output

1
0
2

题目分析

带权并查集的模板题。

之所以能够用并查集做,是因为:即便集合内每一个元素不是完全等价的,但它满足能够独立带权的性质。

嗯……如果是初学带权并查集的话还是无视上面那句话好了。学的时候还是靠代码理解,理解之后自然就会有自己对于一块方面的总结了。

对于每一个维护$dis[i]$和$sum[i]$,其中$dis[i]$表示它下面有几个方块;$sum[i]$表示它这摞方块一共有几个。维护两个量是为了方便合并时的转移。

因为这题有上下之分,所以合并过程是既不能随便合并(破坏顺序);也难以按秩合并(麻烦)。路径压缩看上去好像也不行,然而实际上可以这样操作:保留逻辑上的上下顺序(换句话说,就是我们在考虑问题时候当做它是上下有序),但是操作时就路径压缩(运行结果上来看,元素之间路径被压缩了,因此并没有上下顺序)。

这样便发现,合并时候把整摞方块的最下面方块作为根是更方便的。

 #include<cstdio>
#include<cctype>
const int maxn = ; int fa[maxn],sum[maxn],dis[maxn];
int q; int get(int x)
{
if (fa[x]!=x){
int tt = fa[x];
fa[x] = get(fa[x]);
dis[x] += dis[tt];
}
return fa[x];
}
void unions(int x, int y)
{
fa[x] = y;
dis[x] += sum[y];
sum[y] += sum[x];
}
int main()
{
scanf("%d",&q);
for (int i=; i<=; i++) fa[i] = i, sum[i] = ;
for (int i=; i<=q; i++)
{
char ch = getchar();
while (!isalpha(ch)) ch = getchar();
int x,y;
if (ch=='M'){
scanf("%d%d",&x,&y);
int fx = get(x), fy = get(y);
if (fx!=fy) unions(fx, fy);
}else{
scanf("%d",&x);
get(x);
printf("%d\n",dis[x]);
}
}
return ;
}

END

初涉「带权并查集」&&bzoj3376: [Usaco2004 Open]Cube Stacking 方块游戏的更多相关文章

  1. bzoj3376/poj1988[Usaco2004 Open]Cube Stacking 方块游戏 — 带权并查集

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3376 题目大意: 编号为1到n的n(1≤n≤30000)个方块正放在地上.每个构成一个立方 ...

  2. 【BZOJ 3376】[Usaco2004 Open]Cube Stacking 方块游戏 带权并查集

    这道题一开始以为是平衡树结果发现复杂度过不去,然后发现我们一直合并而且只是记录到最低的距离,那么就是带权并查集了,带权并查集的权一般是到根的距离,因为不算根要好打,不过还有一些其他的,具体的具体打. ...

  3. bzoj 3376 [Usaco2004 Open]Cube Stacking 方块游戏——带偏移量的并查集

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3376 带偏移量的并查集. #include<iostream> #include ...

  4. BZOJ 3376 [Usaco2004 Open]Cube Stacking 方块游戏(带权并查集)

    题解 #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #in ...

  5. POJ 1703 Find them, Catch them(带权并查集)

    传送门 Find them, Catch them Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 42463   Accep ...

  6. [NOIP摸你赛]Hzwer的陨石(带权并查集)

    题目描述: 经过不懈的努力,Hzwer召唤了很多陨石.已知Hzwer的地图上共有n个区域,且一开始的时候第i个陨石掉在了第i个区域.有电力喷射背包的ndsf很自豪,他认为搬陨石很容易,所以他将一些区域 ...

  7. poj1417 带权并查集 + 背包 + 记录路径

    True Liars Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2713   Accepted: 868 Descrip ...

  8. poj1984 带权并查集(向量处理)

    Navigation Nightmare Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 5939   Accepted: 2 ...

  9. 【BZOJ-4690】Never Wait For Weights 带权并查集

    4690: Never Wait for Weights Time Limit: 15 Sec  Memory Limit: 256 MBSubmit: 88  Solved: 41[Submit][ ...

随机推荐

  1. Python爬虫|爬取喜马拉雅音频

    "GOOD Python爬虫|爬取喜马拉雅音频 喜马拉雅是知名的专业的音频分享平台,用户规模突破4.8亿,汇集了有声小说,有声读物,儿童睡前故事,相声小品等数亿条音频,成为国内发展最快.规模 ...

  2. MyBatist庖丁解牛(四)

    什么是MyBatis-Spring? MyBatis-Spring就是帮助你将MyBatis代码无缝的整合到Spring中.Spring将会加载必要的sqlSessionFactory类和sessio ...

  3. SQL必知必会03 计算字段 获取当前日期时间 日期时间格式化

  4. A - Bi-shoe and Phi-shoe

    每一个数字的欧拉函数要大于或等于该数字.求,最小的欧拉函数的下标和的大小. 答案要用longlong存 #include <iostream> #include <algorithm ...

  5. 转:在linux中vi 文件里行尾奇怪的^M及解决

    Linux编辑器vim中删除行尾的^M 有时候,在 Linux 中使用打开曾在 Windows 中编辑过的文件时,会在行尾看到 ^M 字符.看起来总是感觉很别扭. 删除方法如下: 在 Vim 的命令模 ...

  6. 蜥蜴-DInic

    题目背景 07四川省选 题目描述 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴 ...

  7. C#入门笔记1

    C#是用于创建要运行在.NET CLR上的应用程序的语言之一,从C和C++语言演化而来,是微软专门为使用.NET平台而创建的.优点:就是彻头彻尾为.NET Framework设计语言. C#能编写什么 ...

  8. gcc&g++

    原文章 误区一:gcc只能编译c代码,g++只能编译c++代码两者都可以,但是请注意:1.后缀为.c的,gcc把它当作是C程序,而g++当作是c++程序:后缀为.cpp的,两者都会认为是c++程序,注 ...

  9. 纯css实现div三列等高布局的最简单方法简化版/也可以多列

    使用正padding和负margin对冲实现多列布局方法 这种方法很简单,就是在所有列中使用正的上.下padding和负的上.下margin,并在所有列外面加上一个容器,并设置overflow:hid ...

  10. (WWWWWWWWWW)codevs 3305 水果姐逛水果街Ⅱ

    写这么长了不A有点舍不得.. 想A又调不出来.. 于是乎就存一下.. 屠龙宝刀点击就送 #include <cstdio> #include <vector> #define ...