银河英雄传说[NOI2002]
题目描述
公元五八○一年,地球居民迁移至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展。
宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争。泰山压顶集团派宇宙舰队司令莱因哈特率领十万余艘战舰出征,气吞山河集团点名将杨威利组织麾下三万艘战舰迎敌。
杨威利擅长排兵布阵,巧妙运用各种战术屡次以少胜多,难免恣生骄气。在这次决战中,他将巴米利恩星域战场划分成30000列,每列依次编号为1, 2, …, 30000。之后,他把自己的战舰也依次编号为1, 2, …, 30000,让第i号战舰处于第i列(i = 1, 2, …, 30000),形成“一字长蛇阵”,诱敌深入。这是初始阵形。当进犯之敌到达时,杨威利会多次发布合并指令,将大部分战舰集中在某几列上,实施密集攻击。合并指令为M i j,含义为让第i号战舰所在的整个战舰队列,作为一个整体(头在前尾在后)接至第j号战舰所在的战舰队列的尾部。显然战舰队列是由处于同一列的一个或多个战舰组成的。合并指令的执行结果会使队列增大。
然而,老谋深算的莱因哈特早已在战略上取得了主动。在交战中,他可以通过庞大的情报网络随时监听杨威利的舰队调动指令。
在杨威利发布指令调动舰队的同时,莱因哈特为了及时了解当前杨威利的战舰分布情况,也会发出一些询问指令:C i j。该指令意思是,询问电脑,杨威利的第i号战舰与第j号战舰当前是否在同一列中,如果在同一列中,那么它们之间布置有多少战舰。
作为一个资深的高级程序设计员,你被要求编写程序分析杨威利的指令,以及回答莱因哈特的询问。
最终的决战已经展开,银河的历史又翻过了一页……
输入
输入的第一行有一个整数T(1<=T<=500,000),表示总共有T条指令。
以下有T行,每行有一条指令。指令有两种格式:
1.M i j :i和j是两个整数(1<=i , j<=30000),表示指令涉及的战舰编号。该指令是莱因哈特窃听到的杨威利发布的舰队调动指令,并且保证第i号战舰与第j号战舰不在同一列。
2.C i j :i和j是两个整数(1<=i , j<=30000),表示指令涉及的战舰编号。该指令是莱因哈特发布的询问指令。
输出
你的程序应当依次对输入的每一条指令进行分析和处理:
如果是杨威利发布的舰队调动指令,则表示舰队排列发生了变化,你的程序要注意到这一点,但是不要输出任何信息;
如果是莱因哈特发布的询问指令,你的程序要输出一行,仅包含一个整数,表示在同一列上,第i号战舰与第j号战舰之间布置的战舰数目。如果第i号战舰与第j号战舰当前不在同一列上,则输出-1。
样例输入
4
M 2 3
C 1 2
M 2 4
C 4 2
样例输出
-1
1 题解
题目很复杂,做法很简单。在考场上明知道要用并查集,还是改着改着就把并查集删掉了。大概清楚要维护哪些变量,一队里的战舰数zg[sj],到队首的战舰数qj[sj],队首战舰fa[sj]。只是没有掌握压缩路径的技巧(并查集连压缩路径的基本方法都忘了?!),无怪乎越打越觉得并查集不太对劲,没有路径压缩肯定会迭代次数过多,根本没有正确的可能。考虑过链表,觉得不大好实现。用并查集,每次压缩路径前把父亲前的战舰数加到儿子前的战舰数上;合并时把父亲所在集合的战舰数加到儿子前的战舰数,再把子集合的战舰数加到父集合里。
int find(int x)
{
if(x==fa[x])
return x;
int temp;
temp=find(fa[x]);
qj[x]+=qj[fa[x]];
fa[x]=temp;
return fa[x];
}
void hb(int x,int y)
{
x=find(x);
y=find(y);
fa[x]=y;
qj[x]+=zg[y];
zg[y]+=zg[x];
}
从寒假到现在几乎没有打过并查集,重要的地方除了合并、查找两个函数,大概就是路径压缩了。这道题展示了一种维护集合中元素与祖先关系的方法,要特别注意压缩路径与变量赋值的先后关系。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
using namespace std;
const int sj=,zj=;
int ca,fa[sj],qj[sj],zg[sj],a1,a2;
char ss;
void init()
{
scanf("%d",&ca);
for(int i=;i<=zj;i++)
{
fa[i]=i;
zg[i]=;
qj[i]=;
}
}
int find(int x)
{
if(x==fa[x])
return x;
int temp;
temp=find(fa[x]);
qj[x]+=qj[fa[x]];
fa[x]=temp;
return fa[x];
}
void hb(int x,int y)
{
x=find(x);
y=find(y);
fa[x]=y;
qj[x]+=zg[y];
zg[y]+=zg[x];
}
int main()
{
freopen("galaxy.in","r",stdin);
freopen("galaxy.out","w",stdout);
init();
for(int l=;l<=ca;l++)
{
scanf("%s",&ss);
scanf("%d%d",&a1,&a2);
if(ss=='M')
hb(a1,a2);
if(ss=='C')
{
if(find(a1)!=find(a2))
printf("-1\n");
else
{
if(qj[a1]>qj[a2])
printf("%d\n",qj[a1]-qj[a2]-);
else
printf("%d\n",qj[a2]-qj[a1]-);
}
}
}
//while(1);
return ;
}
我两岁的时候万万没有想到我将来还会做这一年的NOI题= =
银河英雄传说[NOI2002]的更多相关文章
- OI暑假集训游记
莞中OI集训游记 Written BY Jum Leon. I 又是一载夏,本蒟蒻以特长生考入莞中,怀着忐忑的心情到了8月,是集训之际.怀着对算法学习的向往心情被大佬暴虐的一丝恐惧来到了 ...
- 【NOI2002】银河英雄传说(并查集)
[NOI2002]银河英雄传说 题面 题目描述 公元五八○一年,地球居民迁至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军 ...
- 【洛谷】P1196 [NOI2002]银河英雄传说【带权并查集】
P1196 [NOI2002]银河英雄传说 题目描述 公元五八○一年,地球居民迁至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的 ...
- NOI2002银河英雄传说-带权并查集
[NOI2002]银河英雄传说-带权并查集 luogu P1196 题目描述 Description: 公元五八○一年,地球居民迁至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年, ...
- P1196 [NOI2002]银河英雄传说(并查集)
P1196 [NOI2002]银河英雄传说(并查集) 本题关键 用两个一维数组表示了一个稀疏的二维数组. 这两个一维数组一个表示祖先(就是最前面那个),一个表示距离祖先的距离. 并且还有一个关键点是, ...
- 「洛谷P1196」「NOI2002」银河英雄传说 解题报告
P1196 [NOI2002]银河英雄传说 题目描述 公元五八○一年,地球居民迁至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的 ...
- 边带权并查集 学习笔记 & 洛谷P1196 [NOI2002] 银河英雄传说 题解
花了2h总算把边带权并查集整明白了qaq 1.边带权并查集的用途 众所周知,并查集擅长维护与可传递关系有关的信息.然而我们有时会发现并查集所维护的信息不够用,这时"边带权并查集"就 ...
- 洛谷P1196[NOI2002]银河英雄传说-并查集扩展
银河英雄传说 题意:在并查集的基础上,还要求出同一集合的两个点的距离 这道题用并查集自己是知道的,但是竟然可以这么骚的操作. 下面转自大佬的查详细题解 初见这道题,首先想到的方法当然是直接模拟,模拟每 ...
- noi2002银河英雄传说(并查集)
首先表示对C++读入读出问题复杂程度的敬畏,看了好多没讲明白的,本题用cin竟然过不了评测,搞scanf的读入搞了好久.... 本题确实是一道经典的并查集题型,不多讲,拿来练练手用的(其中经历很惨) ...
随机推荐
- redmine测试使用小结
在尽量不影响当前项目活动的情况下,可以对测试过程作部分改进,能够支持建立项目的BUG管理过程,简述如下: 1.配置角色和权限->新建角色:测试人员 (1)主要配置问题跟踪权限 (2)提前规划好再 ...
- Java代码实现 增删查 + 分页——实习第四天
今天项目内容已经开始了,并且已经完成好多基本操作,今天就开始总结今天学习到的内容,和我遇到的问题,以及分析这其中的原因. 内容模块: 1:Java代码实现对数据库的增删查: 2:分页且获取页面信息: ...
- 浅谈js中的正则表达式
很多时候多会被正则表达式搞的晕头转向,最近抽出时间对正则表达式进行了系统的学习,整理如下: 正则表达式的创建 两种方法,一种是直接写,由包含在斜杠之间的模式组成:另一种是调用RegExp对象的构造函数 ...
- Redis客户端管理工具,状态监控工具
TreeNMS是一款Redis web客户端管理工具,采用JAVA开发,实现基于web方式对Redis数据库进行管理.监控.数据维护. 功能包括:数据库的状态监控,库表的展示,key,value的展示 ...
- AI相关 TensorFlow -卷积神经网络 踩坑日记之一
上次写完粗浅的BP算法 介绍 本来应该继续把 卷积神经网络算法写一下的 但是最近一直在踩 TensorFlow的坑.所以就先跳过算法介绍直接来应用场景,原谅我吧. TensorFlow 介绍 TF是g ...
- php取出数组中的最大值
<?php /** * @param $arr * @return mixed * php取出数组中的最大值(方法一) */ function getMax($arr){ $max=$arr[0 ...
- [leetcode-485-Max Consecutive Ones]
Given a binary array, find the maximum number of consecutive 1s in this array. Example 1: Input: [1, ...
- Nio经典工作方式
public void selector() throws IOException { ByteBuffer buffer = ByteBuffer.allocate(1024); Selector ...
- 详解ASP.NET MVC 控制器
1 概述 在阅读本篇博文时,建议结合上篇博文:详解ASP.NET MVC 路由 一起阅读,效果可能会更好些. Controller(控制器)在ASP.NET MVC中负责控制所有客户端与服务端的 ...
- iOS多线程开发之GCD(中篇)
前文回顾: 上篇博客讲到GCD的实现是由队列和任务两部分组成,其中获取队列的方式有两种,第一种是通过GCD的API的dispatch_queue_create函数生成Dispatch Queue:第二 ...