P2342 叠积木
题目链接
题目背景
Cube Stacking, 2004 Open

题目描述
约翰和贝西在叠积木。共有30000块积木,编号为1到30000。一开始,这些积木放在地上,自然地分成N堆。贝西接受约翰的指示,把一些积木叠在另一些积木的上面。一旦两块积木相叠, 彼此就再也不会分开了,所以最后叠在一起的积木会越来越高。约翰让贝西依次执行P条操作,操作分为两种:

? 第一种是移动操作,格式为“移动X到Y的上面”。X和Y代表两块积木的编号,意思是将X所的那堆积木,整体叠放到Y所在的那堆积木之上;

? 第二种是统计操作,格式为“统计Z下方的积木数量”。Z代表一块积木的编号,意思是贝西需要报告在编号为Z的积木之下还有多少块积木

请编写一个程序,帮助贝西回答每条统计问题。

输入格式:
? 第一行:单个整数:P,1 ≤ P ≤ 10^5

? 第二行到第P + 1行:每行描述一条命令,如果这行开头的字母是 M,代表一条移动命令,后面的两个整数代表上文中的X和Y;如果开头字母是 C,代表一条统计命令。后面的整数代表上文中的Z,保证所有的移动命令都有意义,X和Y不会已经出现在同一堆积木里

输出格式:
? 对每一个统计命令,输出正确回答,用换行符分开每个查询的结果

输入样例:
6
M 1 6
C 1
M 2 4
M 2 6
C 3
C 4
输出样例:
1
0
2
说明
第一次查询时, 1 下面只有一个 6;第二次查询时, 3 下面没有任何积木;第三次查询时,4 下面有两块积木:1 和 6

题解
真不知道洛谷题时是不是没人会加LG前缀

这题最容易想到的就是利用并查集来求。

用C数组表示每个箱子下面的箱子个数。
我们不可能每次移动后去更新每个箱子。
显然,那样效率太低了。

解决方案之一就是每次推的时候(即刷并查集的时候)修正。

想象一下(或者打开你的mspaint.exe),如果现在我们把一个积木 1 移动到另一个积木 2 上面,我们应该把谁设为父节点?

经过尝试你会发现,如果把 1 设为父节点,也就是把最顶上的设为父节点。
假设 1 为这堆最顶上的,2 为这堆最底下的。
那么当你把这堆东西放到另一堆东西上时,你会发现 2 以下下的积木数量修正以后无法传递给上面的积木。(路径压缩后的并查集是多叉树,难以继续修正)
而询问 2 上面积木的时候也不知道该通过谁来修正一趟。

所以,我们还是把最底层的设为根节点。

接下来,我们考虑一下怎么修正。

如果把 1 移到以 2 为堆底的那堆上面,又把 2 移动到其他东西上面,此时我们再求 1 的父节点时的便利过程:
1->2->fa[2]->……end,最终 1 的父节点会被修正成 end。
(压缩路径后为多叉树)
我们把一棵以 2 为根树接到一棵以 end 为根的树上(接在end上),然后需要在压缩路径的同时修正答案。
(2 的答案以及修正了)

我们从 2 的一个子节点开始看,可以发现我们只需把 2 的答案叠加给它就好了。
因为 c[2] 原本为 0(因为它是堆底,下面不可能有东西),这样也保证了我们重复求一个点祖先的时候不会把答案叠加重复。

那么,如果是 2 的儿子的儿子呢?
既然它不是 2 的直属,那么说明这条路径没压缩过。假设 2 有个儿子 x,这个 x 也有个儿子 y,显然,y 的祖先从 x 变成 2 的时候,也并没有把增加的代价叠加过来,而增加的代价正好是 x 当前的值。

真妙啊,此时会发现,或许给 C 数组换一个定义就可以更好地理解。

C[x] 表示:节点 x 的子节点的懒惰标记。

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=3e4+5;
int n=3e4,m,fa[maxn],ans[maxn],H[maxn];
int rad()
{int ret=0,f=1;char ch=getchar();while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}while (ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();return ret*f;
}
int get(int x)
{return x!=fa[x]?get(fa[x]),ans[x]+=ans[fa[x]],fa[x]=fa[fa[x]]:x;
}
int main()
{m=rad();for (int i=1;i<=n;++i) fa[i]=i,ans[i]=0,H[i]=1;char ch;for (int i=1;i<=m;++i){cin>>ch;if (ch=='M'){int x=get(rad()),y=get(rad());if (x==y) continue;fa[x]=y;ans[x]+=H[y];H[y]+=H[x];}else{int x=rad();get(x);printf("%d\n",ans[x]);}}return 0;
}

LG-P2342 叠积木相关推荐

  1. 刷题记录(NC235611 牛牛国的战争,NC23803 DongDong认亲戚,NC235622 叠积木)

    NC235611 牛牛国的战争 题目链接 关键点 1.因为要在能击败所有敌军的基础下,求存活最多的数量,那么我们可以对敌军的防御力从大到小排列,对于友军的攻击力从大到小排列,这样遍历一次敌军,将所有可 ...

  2. 华为机试真题 C++ 实现【叠积木】

    目录 题目 思路 考点 Code 题目 有一堆长方体积木,它们的长度和宽度都相同,但长度不一. 小橙想把这堆积木叠成一面墙,墙的每层可以放一个积木,也可以将两个积木拼接起来,要求每层的长度相同. 若必 ...

  3. 叠积木/银河系英雄传说[NOI2002]题解

    题目右转 luogu P2342 其实这道题和 [NOI2002]银河英雄传说 一模一样(双倍经验) 言归正传: 题目中的 "移动 \(X\) 到 \(Y\) 的上面" 操作可以看 ...

  4. 华为OD机试真题 Python 实现【叠积木】

    目录 题目 思路 考点 Code 题目 有一堆长方体积木,它们的长度和宽度都相同,但长度不一. 小橙想把这堆积木叠成一面墙,墙的每层可以放一个积木,也可以将两个积木拼接起来,要求每层的长度相同. 若必 ...

  5. 华为od机试: 叠积木

    import java.util.Arrays; import java.util.Scanner;public class Solution_回溯 {public static void main( ...

  6. 洛谷P2342-叠积木

    Problem 洛谷P2342-叠积木 Accept: 373   Submit: 1.1k Time Limit: 1000 mSec    Memory Limit : 128MB Problem ...

  7. 搭积木(block)

    [问题描述] 小 OY 是一个喜欢搭积木的孩子,他有一天决定向小 C 展示他特别的搭积木 技巧. 现在一条直线上从左到右有 n 个位置,标号 1..n,第 i 个位置坐标为 x_i. 每个位置上都预先 ...

  8. iOS11正式推出,第一批AR应用上线App Store!

    今天苹果推出了iOS11正式版,其能够适配包括下至iPhone5s以及最近几款iPad的"数以百万计的设备",如果你的设备也能升级到该系统,意味着接下来可以享用一个全新的App S ...

  9. 情人节,我表白了CSDN小姐姐后,竟然...【为表白写了一个绘图工具,让我不再手残】

    情人节,我表白了CSDN小姐姐后,竟然-竟然有人看了这篇文. 以下图片素材由一个还没写完的工具绘制,稍后会放在CSDN的代码仓库(现在能用了,还没时间改,颜色填充算法还没写,有能力的朋友可以修改一下) ...

  10. 万字长文丨1分36秒,100亿,支付宝技术双11答卷:没有不可能

    2019年双11来了.1分36秒100亿,5分25秒超过300亿,12分49秒超500亿--如果没有双11,中国的互联网技术要发展到今天的水平,或许要再多花20年. 从双11诞生至今的11年里,有一个 ...

最新文章

  1. 全局变量、静态全局变量、静态局部变量和局部变量的区别
  2. 查看Hive SQL执行日志
  3. python的总结与心得词云设计理念_Python编程语言:使用词云来表示学习和工作报告的主题...
  4. AndroidStudio_Gradle介绍以及在androidstudio中的使用---Android原生开发工作笔记76
  5. python关键词提取源码,python实现textrank关键词提取
  6. 成都电子神技大学模拟题(取模运算)
  7. 计算机语言丛书学习:C\C++\JAVA\Python 基础-案例-应用
  8. 计算机窗口显示桌面,Windows Server 2012 R2在桌面上显示计算机/网络图标
  9. Dynamics AX2012 保留上一次操作记录
  10. 威纶通宏指令是c语言吗,威纶触摸屏宏指令使用说明
  11. TOGAF 架构内容框架
  12. 信锐(SUNDRAY)无线控制器wifi无线上网短信认证设置流程
  13. netty实战pdf下载,深度解密:Java与线程的关系
  14. windows下基于selenium保存网页为图片
  15. 程序员的我,为何来了大北京
  16. 不借助idea开发工具构建一个Javaweb项目
  17. 新一代三维GIS技术体系再升维
  18. Dedecms QQ一键登录插件
  19. linux串口特殊字符不能接收
  20. 监控系统介绍和zabbix的安装及配置

热门文章

  1. 装修首页自定义全屏视频播放效果gif动态图片制作视频教程播放代码操作设置全屏居中阿里巴巴国际站
  2. 一幅图理解计算机系统硬件组成
  3. C#多线程之解决多线程编程中大并发数等待唤醒的问题
  4. 电子墨水+android+平板,请推荐一款电子墨水屏的安卓平板
  5. 电脑如何去除视频水印?
  6. JimuReport积木报表 — SQL数据源报表制作
  7. java redo_redo和undo区别讨论
  8. xfce实现桌面图标透明
  9. 苹果电脑教程之退出ID账号
  10. 金蝶K3安装环境检测缺少microsoft vm for java组件解决办法