「洛谷P1196」「NOI2002」银河英雄传说 解题报告
P1196 [NOI2002]银河英雄传说
题目描述
公元五八○一年,地球居民迁至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展。
宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争。泰山压顶集团派宇宙舰队司令莱因哈特率领十万余艘战舰出征,气吞山河集团点名将杨威利组织麾下三万艘战舰迎敌。
杨威利擅长排兵布阵,巧妙运用各种战术屡次以少胜多,难免恣生骄气。在这次决战中,他将巴米利恩星域战场划分成\(30000\)列,每列依次编号为\(1, 2, …,30000\)。之后,他把自己的战舰也依次编号为\(1, 2, …, 30000\),让第\(i\)号战舰处于第\(i\)列\((i = 1, 2, …, 30000)\),形成“一字长蛇阵”,诱敌深入。这是初始阵形。当进犯之敌到达时,杨威利会多次发布合并指令,将大部分战舰集中在某几列上,实施密集攻击。合并指令为\(M_{i,j}\),含义为第i号战舰所在的整个战舰队列,作为一个整体(头在前尾在后)接至第j号战舰所在的战舰队列的尾部。显然战舰队列是由处于同一列的一个或多个战舰组成的。合并指令的执行结果会使队列增大。
然而,老谋深算的莱因哈特早已在战略上取得了主动。在交战中,他可以通过庞大的情报网络随时监听杨威利的舰队调动指令。
在杨威利发布指令调动舰队的同时,莱因哈特为了及时了解当前杨威利的战舰分布情况,也会发出一些询问指令:\(C_{i,j}\)。该指令意思是,询问电脑,杨威利的第ii号战舰与第jj号战舰当前是否在同一列中,如果在同一列中,那么它们之间布置有多少战舰。
作为一个资深的高级程序设计员,你被要求编写程序分析杨威利的指令,以及回答莱因哈特的询问。
最终的决战已经展开,银河的历史又翻过了一页……
输入输出格式
输入格式:
第一行有一个整数\(T(1 \le T \le 500,000)\),表示总共有TT条指令。
以下有\(T\)行,每行有一条指令。指令有两种格式:
- \(M_{i,j}\) :\(i\)和\(j\)是两个整数\((1 \le i,j \le 30000)\),表示指令涉及的战舰编号。该指令是莱因哈特窃听到的杨威利发布的舰队调动指令,并且保证第ii号战舰与第jj号战舰不在同一列。
- \(C_{i,j}\) :\(i\)和\(j\)是两个整数\((1 \le i,j \le 30000)\),表示指令涉及的战舰编号。该指令是莱因哈特发布的询问指令。
输出格式:
依次对输入的每一条指令进行分析和处理:
如果是杨威利发布的舰队调动指令,则表示舰队排列发生了变化,你的程序要注意到这一点,但是不要输出任何信息;
如果是莱因哈特发布的询问指令,你的程序要输出一行,仅包含一个整数,表示在同一列上,第\(i\)号战舰与第\(j\)号战舰之间布置的战舰数目。如果第\(i\)号战舰与第\(j\)号战舰当前不在同一列上,则输出\(-1\)。
输入输出样例
输入样例#1:
4
M 2 3
C 1 2
M 2 4
C 4 2
输出样例#1:
-1
1
说明
【样例说明】
战舰位置图:表格中阿拉伯数字表示战舰编号
写在前面
这是一道边带权并查集的好题。(我的题解可能对不了解并查集的人不太友好)
思路
我们很容易想到记录每只船在某处排行位置,然后询问时直接减一减就可以了。就这样,问题转换为如何保留每个数的位置(d[i])。
Hint:注意,为了方便,我们把d[i]记作相对f[i]的位置。
当一列船(记为A 首只船为 a)合并到另一列(记为B 首只船为b)时,我们为了让a直接以b为父亲,我们要记录每一列船的只数(s[i]),将d[a]修改为s[a] + 1(连到最后时rank为原来船数+1),别忘了修改s[b]与f[a]的值。对于后面父亲不为B的先不管。当寻找祖先时,对于父亲是祖先的船,我们不用修改,因为在合并时已经修改过了,而对于父亲不是祖先的船,我们可以先修改它的父亲(递归进行),是他的父亲的父亲为它的老祖宗,然后把它的d[i] = d[i] + d[f[i]];这样就把参照物改为他的祖宗,实现了路径压缩。
代码很短,只有一点点。。。
代码
#include<bits/stdc++.h>
using namespace std;
#define N 30000
int T;
int f[N + 5], d[N + 5], s[N + 5];
int find( int x ){
if ( f[x] == x ) return x;
int fa(find(f[x]));
d[x] = d[x] + d[f[x]] - 1;
return f[x] = fa;
}
void Merge( int x, int y ){
x = find(x); y = find(y);
if ( x == y ) return;
f[x] = y; d[x] = s[y] + 1; s[y] += s[x];
}
int main(){
scanf( "%d", &T );
for ( int i = 1; i <= N; ++i ) f[i] = i, d[i] = 1, s[i] = 1;
while( T-- ){
char t; int x, y;
while( ( t = getchar() ) != 'M' && t != 'C' );
scanf( "%d%d", &x, &y );
if ( t == 'M' ) Merge( x, y );
else{
if ( find(x) == find(y) ){
if ( x == y ) printf("0\n");
else if ( d[x] > d[y] ) printf( "%d\n", d[x] - d[y] - 1 );
else printf( "%d\n", d[y] - d[x] - 1 );
} else printf( "-1\n" );
}
}
return 0;
}
「洛谷P1196」「NOI2002」银河英雄传说 解题报告的更多相关文章
- 洛谷 P1291 [SHOI2002]百事世界杯之旅 解题报告
P1291 [SHOI2002]百事世界杯之旅 题目描述 "--在2002年6月之前购买的百事任何饮料的瓶盖上都会有一个百事球星的名字.只要凑齐所有百事球星的名字,就可参加百事世界杯之旅的抽 ...
- 洛谷 P4345 [SHOI2015]超能粒子炮·改 解题报告
P4345 [SHOI2015]超能粒子炮·改 题意 求\(\sum_{i=0}^k\binom{n}{i}\),\(T\)组数据 范围 \(T\le 10^5,n,j\le 10^{18}\) 设\ ...
- 洛谷 P1691 有重复元素的排列问题 解题报告
P1691 有重复元素的排列问题 题目描述 设\(R={r_1,r_2,--,r_n}\)是要进行排列的\(n\)个元素.其中元素\(r_1,r_2,--,r_n\)可能相同.使设计一个算法,列出\( ...
- 洛谷 P2746 [USACO5.3]校园网Network of Schools 解题报告
P2746 [USACO5.3]校园网Network of Schools 题目描述 一些学校连入一个电脑网络.那些学校已订立了协议:每个学校都会给其它的一些学校分发软件(称作"接受学校&q ...
- 洛谷 P1121 环状最大两段子段和 解题报告
P1121 环状最大两段子段和 题目描述 给出一段环状序列,即认为\(A_1\)和\(A_N\)是相邻的,选出其中连续不重叠且非空的两段使得这两段和最大. 输入输出格式 输入格式: 第一行是一个正整数 ...
- 洛谷 P1120 小木棍 [数据加强版]解题报告
P1120 小木棍 [数据加强版] 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它 ...
- 洛谷 P2336 [SCOI2012]喵星球上的点名 解题报告
P2336 [SCOI2012]喵星球上的点名 题目描述 a180285 幸运地被选做了地球到喵星球的留学生.他发现喵星人在上课前的点名现象非常有趣. 假设课堂上有 \(N\) 个喵星人,每个喵星人的 ...
- 洛谷 P2862 [USACO06JAN]把牛Corral the Cows 解题报告
P2862 [USACO06JAN]把牛Corral the Cows 题目描述 Farmer John wishes to build a corral for his cows. Being fi ...
- 洛谷 P1344 [USACO4.4]追查坏牛奶Pollutant Control 解题报告
P1344 [USACO4.4]追查坏牛奶Pollutant Control 题目描述 你第一天接手三鹿牛奶公司就发生了一件倒霉的事情:公司不小心发送了一批有三聚氰胺的牛奶.很不幸,你发现这件事的时候 ...
随机推荐
- Python基础:24with语句
一:with语句 在Python 2.6 中正式引入的with语句,是用来简化代码的.这与用try-except 和try-finally所想达到的目的前后呼应.try-except 和try-fin ...
- 第二次 C++作业
1.为什么要用函数? 函数是相对独立的,经常使用的功能抽象化表现形式,函数的优势在于,编写之后可以被重复使用,使用时可以只关心函数的功能和使用方法而不必关心函数的具体实现,这样可以有利于代码重用,可以 ...
- 使用FormData格式上传图像并预览图片
前言 做项目时,遇到表单中图像需要跟表单一起提交,这样会造成后台没办法接收到图片.后面上网调查后,明白表单提交时是默认application/x-www-form-urlencoded格式,只接受键值 ...
- PyTorch之前向传播函数自动调用forward
参考:1. pytorch学习笔记(九):PyTorch结构介绍 2.pytorch学习笔记(七):pytorch hook 和 关于pytorch backward过程的理解 3.Pytorch入门 ...
- 在 CentOS 7.3 上安装 nginx 服务为例,说明在 Linux 实例中如何检查 TCP 80 端口是否正常工作
CentOS 7.3 这部分以在 CentOS 7.3 上安装 nginx 服务为例,说明在 Linux 实例中如何检查 TCP 80 端口是否正常工作. 登录 ECS 管理控制台,确认实例所在安全组 ...
- Python--day64--找到作者关联的所有书籍对象、ORM多对多关联查询的原理
找到当前作者关联的所有书籍对象: ORM多对多关联查询的原理: 编辑作者:
- element-ui-——el-uploadexcel导入
布局文件:(选择文件放在了弹框内部——即点击导入按钮后弹框显示,先下载模板再选择文件点击提交按钮才上传) )) { this.$notify({ message: '数据导入成功', type: 's ...
- H3C 主动方式建立连接过程
- JS事件委托(代理)学习笔记
在开始之前我们先来熟悉一下HTML DOM addEventListener()方法,该方法用于向指定元素添加事件句柄.语法说明如下图所示: 主要想强调一下第三个参数useCapture,默认值为fa ...
- luoguP4313 文理分科
luoguP4313 文理分科 复习完之后做了道典型题目. 这道题条件有点多 我们逐个分析 如果没有\(sameart\)或者\(samescience\)的限制,就是一个裸的最大权闭合子图的问题了 ...