当前位置: 首页 > news >正文

P1196 [NOI2002] 银河英雄传说 带权并查集

[NOI2002] 银河英雄传说

题目背景

公元 580158015801 年,地球居民迁至金牛座 α\alphaα 第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展。

宇宙历 799799799 年,银河系的两大军事集团在巴米利恩星域爆发战争。泰山压顶集团派宇宙舰队司令莱因哈特率领十万余艘战舰出征,气吞山河集团点名将杨威利组织麾下三万艘战舰迎敌。

题目描述

杨威利擅长排兵布阵,巧妙运用各种战术屡次以少胜多,难免恣生骄气。在这次决战中,他将巴米利恩星域战场划分成 300003000030000 列,每列依次编号为 1,2,…,300001, 2,\ldots ,300001,2,,30000。之后,他把自己的战舰也依次编号为 1,2,…,300001, 2, \ldots , 300001,2,,30000,让第 iii 号战舰处于第 iii 列,形成“一字长蛇阵”,诱敌深入。这是初始阵形。当进犯之敌到达时,杨威利会多次发布合并指令,将大部分战舰集中在某几列上,实施密集攻击。合并指令为 M i j,含义为第 iii 号战舰所在的整个战舰队列,作为一个整体(头在前尾在后)接至第 jjj 号战舰所在的战舰队列的尾部。显然战舰队列是由处于同一列的一个或多个战舰组成的。合并指令的执行结果会使队列增大。

然而,老谋深算的莱因哈特早已在战略上取得了主动。在交战中,他可以通过庞大的情报网络随时监听杨威利的舰队调动指令。

在杨威利发布指令调动舰队的同时,莱因哈特为了及时了解当前杨威利的战舰分布情况,也会发出一些询问指令:C i j。该指令意思是,询问电脑,杨威利的第 iii 号战舰与第 jjj 号战舰当前是否在同一列中,如果在同一列中,那么它们之间布置有多少战舰。

作为一个资深的高级程序设计员,你被要求编写程序分析杨威利的指令,以及回答莱因哈特的询问。

输入格式

第一行有一个整数 TTT1≤T≤5×1051 \le T \le 5 \times 10^51T5×105),表示总共有 TTT 条指令。

以下有 TTT 行,每行有一条指令。指令有两种格式:

  1. M i jiiijjj 是两个整数(1≤i,j≤300001 \le i,j \le 300001i,j30000),表示指令涉及的战舰编号。该指令是莱因哈特窃听到的杨威利发布的舰队调动指令,并且保证第 iii 号战舰与第 jjj 号战舰不在同一列。

  2. C i jiiijjj 是两个整数(1≤i,j≤300001 \le i,j \le 300001i,j30000),表示指令涉及的战舰编号。该指令是莱因哈特发布的询问指令。

输出格式

依次对输入的每一条指令进行分析和处理:

  • 如果是杨威利发布的舰队调动指令,则表示舰队排列发生了变化,你的程序要注意到这一点,但是不要输出任何信息。
  • 如果是莱因哈特发布的询问指令,你的程序要输出一行,仅包含一个整数,表示在同一列上,第 iii 号战舰与第 jjj 号战舰之间布置的战舰数目。如果第 iii 号战舰与第 jjj 号战舰当前不在同一列上,则输出 −1-11

样例 #1

样例输入 #1

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

样例输出 #1

-1
1

提示

战舰位置图:表格中阿拉伯数字表示战舰编号

带权并查集
我一开始的代码:

#include <bits/stdc++.h>using namespace std;const int maxn=30000;int pre[maxn+5],d[maxn+5],lazy[maxn+5],num[maxn+5],ind[maxn+5];
int T;
char op;void init()
{for(int i=0;i<=maxn;i++){pre[i]=i;d[i]=0;lazy[i]=0;num[i]=1;ind[i]=0;}
}int findroot(int x)
{if(pre[x]==x) return x;int y= pre[x];int rooty=findroot(y);d[x]+= lazy[y];lazy[x]+= lazy[y];if(--ind[y]==0){lazy[y]=0;}pre[x]=rooty;ind[rooty]++;return rooty;
}
void join(int x,int y)
{int rootx=findroot(x);int rooty=findroot(y);pre[rootx]=rooty;d[rootx]+=num[rooty];lazy[rootx]+=num[rooty];num[rooty]+=num[rootx];ind[rooty]++;
}void query(int x,int y)
{int rootx=findroot(x);int rooty=findroot(y);if (rootx!=rooty){puts("-1");return;}int maxi=max(d[x],d[y]);int mini=min(d[x],d[y]);printf("%d\n", max(maxi-mini-1,0) );}
int main()
{int x,y;while(~scanf("%d",&T)){init();while(T--){scanf(" %c%d%d",&op,&x,&y);if(op=='M'){join(x,y);}else if(op=='C'){query(x,y);}}}return 0;
}

看了题解,发现不用使用lazy数组。
因为d[]维护的是当前结点相对于根结点的距离。
每个结点x的d[x]初始化时是0,只有一次机会作为根结点合并到其它根结点rooty,此时d[x]会有更新。
同时当x的父亲节点y=pre[x]指向新的父结点时,会更新d[y],之后调用findroot(x)也会更新d[x]。

#include<iostream>
#include<cmath>
using namespace std;
int f[30001],s[30001],b[30001];
int find(int o)//查找
{if(f[o]==o) return o;int k=f[o];f[o]=find(f[o]);//路径压缩s[o]+=s[k];//更新当前节点到根的距离return f[o];
}
int main()
{int n;cin>>n;for(int i=1;i<=30000;i++) {f[i]=i;s[i]=0;b[i]=1;}for(int i=1;i<=n;i++){char ch;int x,y,dx,dy;cin>>ch>>x>>y;if(ch=='M'){dx=find(x);//查找x的根dy=find(y);//查找y的根f[dx]=dy;//把x放在y后面s[dx]+=b[dy];//更新x的根到新的根的距离b[dx]+=b[dy];//更新集合大小b[dy]=b[dx];//更新集合大小}if(ch=='C'){dx=find(x);dy=find(y);if(dx!=dy){cout<<-1<<endl;continue;}//不在同一个集合中cout<<abs(s[x]-s[y])-1<<endl;//中间战舰的数量等于x到根的距离减y到根的距离减一。}}return 0;
}

总结:

  1. 使用并查集,当一个结点x指向的结点变化时pre[x]
    无非一下两种情况: 1) x作为根结点 合并到 另一个树的根结点。
  1. x或其子树内结点调用查找操作,将x指向了根结点rootx。

相关文章:

P1196 [NOI2002] 银河英雄传说 带权并查集

[NOI2002] 银河英雄传说 题目背景 公元 580158015801 年&#xff0c;地球居民迁至金牛座 α\alphaα 第二行星&#xff0c;在那里发表银河联邦创立宣言&#xff0c;同年改元为宇宙历元年&#xff0c;并开始向银河系深处拓展。 宇宙历 799799799 年&#xff0c;银河系的两大军…...

【项目实战】快来入门Groovy的基础语法吧

一、Groovy是什么? 1.1 与Java语言的关系 下一代的Java 语言,增强Java平台的唯一的脚本语言跟java一样,它也运行在 JVM 中。支持Java平台,无缝的集成了Java 的类和库;Groovy是一种运行在JVM上的动态语言,跑在JVM中的另一种语言编译后的.groovy也是以class的形式出现的。1…...

Mybatis中的动态SQL

Mybatis中的动态SQL 当存在多条件查询的SQL时&#xff0c;当用户某个条件的属性没有写时&#xff0c;就会存在问题&#xff0c;在test中则不能很好的运行 所以Mybatis提出了动态SQL。 即判断用户是否输入了某个属性 动态SQL中的一些问题 方法一 这个里的and是为了确保if条…...

VUE常用API

1.$set数据变了&#xff0c;视图没变 this.$set(targe&#xff0c;key&#xff0c;value)2.$nextTick:返回参数[函数]。是一个异步的&#xff0c;功能获得更新后DOM$nextTick(callback){return Promise.resolve().then(()>{callback();}) }3.$refs获取dom4.$el获取当前组件根…...

25 openEuler管理网络-使用nmcli命令配置ip

文章目录25 openEuler管理网络-使用nmcli命令配置ip25.1 nmcli介绍25.2 设备管理25.2.1 连接到设备25.2.2 断开设备连接25.3 设置网络连接25.3.1 配置动态IP连接25.3.1.1 配置IP25.3.1.2 激活连接并检查状态25.3.2 配置静态IP连接25.3.2.1 配置IP25.3.2.2 激活连接并检查状态25…...

如何安装和使用A-ops工具?

一、pip配置 1.配置信任域 ​ pip3 config set global.trusted-host mirrors.tools.huawei.com2.配置pip源的url地址pip3 config set global.index-url http://mirrors.tools.huawei.com/pypi/simple 二、npm安装及配置 npm -v检测系统有无安装npm,如果没有的话需要配置ope…...

MySql数据库环境部署

MySql基础与Sql数据库概述基础环境的建立MYSQL数据库的连接方法MySql的默认数据库数据库端口号数据库概述 数据库&#xff08;DataBase&#xff0c;DB)∶存储在磁带、磁盘、光盘或其他外存介质上、按定结构组织在一起的相关数据的集合。数据库管理系统〈DataBase Management S…...

极品笔记,阿里P7爆款《K8s+Jenkins》技术笔记,职场必备

前些日子从阿里的朋友那里取得这两份K8sJenkins的爆款技术笔记&#xff1a;《K8S(kubernetes)学习指南》《Jenkins持续集成从入门到精通》&#xff0c;非常高质量的干货&#xff0c;我立马收藏&#xff01; 而今天咱们文章的主角就是这非常之干货的技术笔记&#xff1a;K8SJenk…...

数据结构:各种排序方法的综合比较

排序方法的选用应视具体场合而定。一般情况下考虑的原则有:(1)待排序的记录个数 n;(2)记录本身的大小;(3)关键字的分布情况:(4)对排序稳定性的要求等。 1.时间性能 (1) 按平均的时间性能来分,有三类排序方法: 时间复杂度为 O(nlogn)的方法有:快速排序、堆排序和归并排序,其中…...

【设计模式】 策略模式介绍及C代码实现

【设计模式】 策略模式介绍及C代码实现 背景 在软件构建过程中&#xff0c;某些对象使用的算法可能多种多样&#xff0c;经常改变&#xff0c;如果将这些算法都编码到对象中&#xff0c;将会使对象变得异常复杂&#xff0c;而且有时候支持不使用的算法也是一个性能负担。 如何…...

【数据库】第二章 关系数据库

第二章 关系数据库 2.1关系数据结构及形式化定义 关系 域&#xff08;domain) :域是一组具有相同数据类型的值的集合&#xff0c;可以取值的个数叫基数 笛卡尔积 &#xff1a;一个记录叫做一个元组&#xff08;tuple),元组中每一个属性值&#xff0c;叫一个分量 基数&…...

oracle和mysql的分页

oracle的分页&#xff1a;rownum 注意:&#xff1a; 对 ROWNUM 只能使用 < 或 <, 用 、 >、 > 都不能返回任何数据。 rownum是对结果集的编序排列&#xff0c;始终是从1开始&#xff0c;所以rownum直接使用时不允许使用>、> 所以当查询中间部分的信息时&…...

深拷贝与浅拷贝的理解

浅拷贝的理解浅拷贝的话只会拷贝基本数据类型&#xff0c;例如像string、Number等这些&#xff0c;类似&#xff1a;Object、Array 这类的话拷贝的就是对象的一个指针(通俗来讲就是拷贝一个引用地址&#xff0c;指向的是一个内存同一份数据)&#xff0c;也就是说当拷贝的对象数…...

Shell变量

一、变量分类 根据作用域分三种 &#xff08;一&#xff09;只在函数内有效&#xff0c;叫局部变量 &#xff08;二&#xff09;只在当前shell进程中有效&#xff0c;叫做全局变量 &#xff08;三&#xff09;在当前shell进程与子进程中都有效&#xff0c;叫做环境变量 shell进…...

Android 8请求权限时弹窗BUG

弹窗BUG 应用使用requestPermissions申请权限时&#xff0c;系统会弹出一个选择窗口&#xff0c;可进行允许或拒绝&#xff0c; 此窗口中有一个”不再询问“的选择框&#xff0c; ”拒绝”及“允许”的按钮。 遇到一个Bug,单点击“不再询问”&#xff0c;“允许”这个按钮会变…...

路漫漫:网络空间的监管趋势

网络空间是“以相互依存的网络基础设施为基本架构&#xff0c;以代码、信息与数据的流动为环境&#xff0c;人类利用信息通讯技术与应用开展活动&#xff0c;并与其他空间高度融合与互动的空间”。随着信息化技术的发展&#xff0c;网络空间日益演绎成为与现实人类生存空间并存…...

洛谷 P1208 [USACO1.3]混合牛奶 Mixing Milk

最后水一篇水题题解&#xff08;实在太水了&#xff09; # [USACO1.3]混合牛奶 Mixing Milk ## 题目描述 由于乳制品产业利润很低&#xff0c;所以降低原材料&#xff08;牛奶&#xff09;价格就变得十分重要。帮助 Marry 乳业找到最优的牛奶采购方案。 Marry 乳业从一些奶农手…...

数据库的基本查询

注意&#xff1a;LIMIT的两个参数&#xff0c;第一个是起始位置&#xff0c;第二个是一次查询到多少页。注意&#xff1a;什么类型的数字都是可以排序的。日期的降序是从现在到以前&#xff0c;MySQL ENUM值如何排序&#xff1f;在MYSQL中&#xff0c;我们知道每个ENUM值都与一…...

10 分钟把你的 Web 应用转为桌面端应用

在桌面端应用上&#xff0c;Electron 也早已做大做强&#xff0c;GitHub桌面端、VSCode、Figma、Notion、飞书、剪映、得物都基于此。但最近后起之秀的 Tauri 也引人注目&#xff0c;它解决了 Electron 一个大的痛点——打包产物特别大。 我们知道 Electron 基于谷歌内核 Chro…...

Delphi RSA加解密(二)

dll开发环境: Delphi XE 10.1 Berlin exe开发环境: Delphi 6 前提文章: Delphi RSA加解密(一) 目录 1. 概述 2. 准备工作 2.1 下载DEMO程序 2.2 字符编码说明 3. Cryption.dll封装 3.1 接口概况 3.2 uPub.pas单元代码 3.3 uInterface.pas单元代码 3.4 特别注意 4. 主程序…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

el-switch文字内置

el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...