Codeforces Round 875 (Div. 2)(A—D)

news2025/1/17 23:20:03

文章目录

  • A. Twin Permutations
    • 1、分析
    • 2、代码
  • B. Array merging
    • 1、分析
    • 2、代码
  • C. Copil Copac Draws Trees
    • 1、分析
    • 2、代码
  • D. The BOSS Can Count Pairs
    • 1、分析
    • 2、代码

A. Twin Permutations

A. Twin Permutations

1、分析

作者这里的构造方法是让最终的数组满足: a 1 + b 1 = a 2 + b 2 = . . . = a i + b i = n + 1 a_1+b_1=a_2+b_2=...=a_i+b_i=n+1 a1+b1=a2+b2=...=ai+bi=n+1

现在来证明一下这个构造方法的正确性。

因为我们的和是确定的,所以 b i = n + 1 − a i b_i=n+1-a_i bi=n+1ai
由于我们的 a i a_i ai是一个排列,所以 a i a_i ai是两两不同的,因此 b i b_i bi也是两两不同的。因为 a a a的范围是 [ 1 , n ] [1,n] [1,n],所以 b b b的范围是 [ 1 , n ] [1,n] [1,n]。而 b b b数组的长度又是 n n n。因此, b b b数组是一个从 1 1 1 n n n的两两不同的长度为 n n n的数列,即 b b b数组是一个排列。符合题意。

2、代码

#include<bits/stdc++.h>
using namespace std;

void solve()
{
	int n;
	cin >> n;
	vector<int>a(n);
	for(auto &x : a)
		cin >> x;
		
	for(int i = 0; i < n; i ++)
	{
		cout << n - a[i] + 1 << " ";
	}
	cout << endl;
}

signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	int t;
	cin >> t;
	while(t--)
	solve();
}

B. Array merging

B. Array merging

1、分析

这道题有一个很重要的性质,即每次只取两个数组的第一个元素的其中一个。如果没有这个性质的话,直接数一数两个数组中不同数字出现的次数和,输出最大值即可。那么这个性质的存在,又对答案产生了什么影响呢?

这里证明两件事情:

第一件事情:任意两段连续相同数字可以拼接在一起。
在这里插入图片描述假设我们想要将A和B拼在一起,只需要先将A和B前面的数字都取出来,拼接在前面,再取A和B即可。

第二件事情:任意三段及以上连续相同数字无法拼接在一起。
在这里插入图片描述
如上图所示,假设我们想要将ABC三段连接在一起,当我们将A和B连接在一起后,后面就必须接上Q和P中间的数字,也就是说我们A和B组成的连续数字必定被打断,所以C是无法接到A+B的后面的。

通过上面的两个证明,我们可以得到以下结论:
对于任意数字,在两个数组中分别求出最长连续相同数字的个数,再相加。
这样对于任何数字,都能得到一个相加后的数字。再从这些数字里取出一个最大值即可。

#include<bits/stdc++.h>
using namespace std;

void solve()
{
	int n;
	cin >> n;
	vector<int>a(n), b(n);
	for(int i = 0; i < n; i ++)
		cin >> a[i];
	for(int i = 0; i < n; i ++)
		cin >> b[i];
	
	map<int,int>ca, cb;
	for(int i = 0; i < n; i ++)
	{
		int cnt = 1;
		while(i + 1 < n && a[i] == a[i + 1])
			cnt ++, i ++;
		ca[a[i]] = max(ca[a[i]], cnt);
	}
	for(int i = 0; i < n; i ++)
	{
		int cnt = 1;
		while(i + 1 < n && b[i] == b[i + 1])
			cnt ++, i ++;
		cb[b[i]] = max(cb[b[i]], cnt);
	}
	map<int,int>ans;

	for(auto x : ca)
		ans[x.first] += x.second;	

	for(auto x : cb)
		ans[x.first] += x.second;

	int ANS = 0;
	for(auto x : ans)
		ANS = max(x.second, ANS);
	cout << ANS << endl;
}

signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	int t;
	cin >> t;
	while(t--)
	solve();
}

2、代码

C. Copil Copac Draws Trees

C. Copil Copac Draws Trees

1、分析

对于树的问题,我们可以先考虑一条链的情况。
在这里插入图片描述

边上 所标的数字是该边在输入的时候的顺序。根据题意,左图可以依次从上到下涂色,即只需要一次操作。而右图则是一个很极端的情况,右图需要4次操作。

那么有什么规律呢?

我们可以发现下面的规律:
在这里插入图片描述
如果 x < y x<y x<y则在一次操作中,可以将两个点涂色。若 x > y x>y x>y,则在一次操作中,无法同时将两个点操作。这里的 x > y x>y x>y可以看作一个逆序对。

对于一条链而言,操作的次数等于该链上的逆序对个数+1。

接着我们再考虑一棵树的情况。

一棵树可以看做很多条链。
在这里插入图片描述

在第一次操作的过程中,图中的蓝色的点会被成功的涂色。 在第二次操作中,白色的点会被成功涂色。那么最终的答案就是2。我们将这棵树看成各种链,便可以得到下面的情况。
在这里插入图片描述
拆成图中的4条链后,我们就可以利用刚刚的结论,得到每一条链的操作次数。而我们发现,这棵树的答案就是这些链操作次数的最大值。

因此,我们只需要在DFS的过程中,求出每条链的操作次数,再取一个最大值输出即可。

2、代码

#include<bits/stdc++.h>
#define endl '\n'
#define x first
#define y second
using namespace std;
typedef pair<int,int> pii;
const int N = 2e5 + 10;
int e[N], f[N];
vector<pii>edge[N];
int ans = 0;

void dfs(int u, int father)
{
	for(auto [a, b]: edge[u])
	{
		if(a == father)
			continue;
		e[a] = b;
		f[a] = f[u] + (b < e[u]);
		dfs(a, u);
	}	
}

void solve()
{
	int n;
	cin >> n;
	for(int i = 0; i < n - 1; i ++)
	{
		int a, b;
		cin >> a >> b;
		edge[a].push_back({b, i});
		edge[b].push_back({a, i});
	}
	dfs(1, -1);
	int maxv = 0;
	for(int i = 0; i <= n; i ++)
	{
		maxv = max(f[i], maxv);
	}
	cout << maxv + 1 << endl;

	for(int i = 0; i <= n; i ++)
		edge[i].clear();
	for(int i = 0; i <= n; i ++)
		e[i] = f[i] = 0;
}

signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	int t;
	cin >> t;
	while(t--)
	solve();
}

D. The BOSS Can Count Pairs

D. The BOSS Can Count Pairs

1、分析

我们先思考暴力做法,最暴力的做法就是去枚举所有可能的数对,然后再判断这个数对是否满足 a i ∗ a j = b i + b j a_i*a_j=b_i+b_j aiaj=bi+bj。这个过程可以写作 C n 2 = n ( n − 1 ) 2 C_n^2=\frac{n(n-1)}{2} Cn2=2n(n1),即时间复杂度是 O ( n 2 ) O(n^2) O(n2)的。很明显这个做法超时了。

接下来我们想一想如何优化暴力算法。

我们发现这道题有一个很关键的性质: a i ≤ n a_i\leq n ain b i ⪇ n b_i\lneq n bin

这就说明我们的 b i + b j ⪇ 2 n b_i+b_j\lneq2n bi+bj2n,即 a i ∗ a j ≤ 2 n a_i*a_j\leq2n aiaj2n

m i n ( a i , a j ) ⪇ 2 n min(a_i,a_j)\lneq \sqrt{2n} min(ai,aj)2n

那么我们可以去枚举 m i n ( a i , a j ) min(a_i,a_j) min(ai,aj)。(不妨将这个最小值记作 s s s,这个 s s s当作 a j a_j aj)。

然后我们再去枚举数对 ( a i , b i ) (a_i,b_i) (ai,bi)。接着我们就可以利用式子: a i ∗ a j = b i + b j a_i*a_j=b_i+b_j aiaj=bi+bj计算出 b j b_j bj

b j = a i ∗ a j − b i = s ∗ a i − b i b_j=a_i*a_j-b_i=s*a_i-b_i bj=aiajbi=saibi

那么我们的 ( a j , b j ) (a_j,b_j) (aj,bj) ( s , s ∗ a i − b i ) (s,s*a_i-b_i) (s,saibi),而这个数对的个数就是该数对对答案的贡献。

现在我们有两个问题需要解决。

由于我们枚举的是 m i n ( a i , a j ) min(a_i,a_j) min(ai,aj),所以我们需要保证 a i ≥ s a_i\geq s ais的。

如果不这样保证,会出现重复的问题。

同时,为了计算贡献,我们需要开一个数组记录所有 ( s , b i ) (s,b_i) (s,bi)的个数。

如果 a i > s a_i>s ai>s就按照刚刚的推导计算即可。

如果 a i = s a_i=s ai=s的话,这里需要去重。

为什么要去重?

因为此时的 a i = s a_i=s ai=s,所以此时我们选择的两个数对是: ( s , b i ) (s,b_i) (s,bi) ( s , b j ) (s,b_j) (s,bj)。按照刚刚的思路,我们的 ( i , j ) (i,j) (i,j) ( j , i ) (j,i) (j,i)都会被计算进来。实则这两个算一种。

2、代码

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
#define a first
#define b second
using namespace std;
const int N = 1e5 + 10;

void solve()
{
	int n, ans = 0;
	cin >> n;
	vector<pair<int,int>>c(n);
	for(int i = 0; i < n; i ++)
		cin >> c[i].a;
	for(int i = 0; i < n; i ++)
		cin >> c[i].b;
	vector<int>cnt(n + 1);
	for(int s = 1; s * s <= 2 * n; s ++)
	{
		cnt.assign(n + 1, 0);
		for(int i = 0; i < n; i ++)
			if(c[i].a == s)
				cnt[c[i].b] ++;
		int cc = 0;
		for(int i = 0; i < n; i ++)
		{
			if(c[i].a < s)
				continue;
			int x = s * c[i].a - c[i].b;
			if(x < 1 || x > n)
				continue;
			if(c[i].a == s)
				cc += (cnt[x] - (c[i].b == x));
			else
				ans += cnt[x];
		}
		ans += (cc / 2);
	}
	cout << ans << endl;
}

signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	int t;
	cin >> t;
	while(t--)
	solve();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/597509.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux安装jdk8

1.下载jdk8 https://www.oracle.com/java/technologies/downloads/#java8 2.上传jdk &#xff08;1&#xff09;将jdk源码包&#xff0c;上传到/usr/local &#xff08;2&#xff09;进入上传jar包目录 [rootiZ2ze7vthdl3oh0n0hzlu7Z ~]# cd / [rootiZ2ze7vthdl3oh0n0hzlu…

C语言之字符串,内存操作函数详解(一)

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:C语言学习分享⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习更多C语言知识   &#x1f51d;&#x1f51d; 字符串函数 1. 前言&#x1f6a9;2…

电池管理系统 (BMS)

现今的电子设备&#xff0c;小至TWS耳机和可穿戴设备&#xff0c;大至电动汽车&#xff0c;都离不开锂离子或聚合物电池的供电。依据电子设备所需电力的大小&#xff0c;电池组可能由多个电池单元(电芯)排列而成。电池组的充电和放电、输入/输出电压和电流等状态都需要精密监控…

2023年6月DAMA-CDGP数据治理专家认证,你考了吗?

DAMA认证为数据管理专业人士提供职业目标晋升规划&#xff0c;彰显了职业发展里程碑及发展阶梯定义&#xff0c;帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力&#xff0c;促进开展工作实践应用及实际问题解决&#xff0c;形成企业所需的新数字经济下的核心职业…

小白系统地学习it技术--python的心得体会

我对我所学习的IT技术的理解 一、it技术介绍——python二、我学习python前的准备工作三、学习时的具体操作1. 在pycharm练习python&#xff0c;唯手熟尔&#xff01;&#xff01;2. 在bilibili看python学习视频3. 报错了&#xff0c;CSDN是你的不二选择&#xff01;4.找代码&am…

【开发日志】2023.05 ZENO----PrimitiveCurvature----曲率分析工具(几何体、图像、点云)

Screen Space Ambient Occlusion - TDA362/DIT223 - Computer Graphics Labs (chalmers.se)https://www.cse.chalmers.se/edu/course/TDA362/tutorials/ssao.html GAMES102在线课程-刘利刚 (ustc.edu.cn)http://staff.ustc.edu.cn/~lgliu/Courses/GAMES102_2020/default.html …

我给自己搭建的前端导航网站,你们都别用

欢迎关注我&#x1f970;&#x1f970;&#x1f970; 主页传送门&#xff0c;持续产出有思考的文档&#xff5e; &#x1f4a5; 想法来源 前段时间在工作的时候&#xff0c;因为遇到了一些之前没了解过的知识&#xff0c;所以化身百度cv工程师&#xff0c;上网冲浪寻找灵感&am…

第六十一天学习记录:C语言进阶:C语言预处理1

程序的翻译环境和执行环境 在ANSI C的任何一种实现中&#xff0c;存在两个不同的环境。 第一种是翻译环境&#xff0c;在这个环境中源代码被转换为可执行的机器指令。第2种是执行环境&#xff0c;它用于实际执行代码。 详解编译链接 翻译环境 ![在这里插入图片描述](https:/…

实战:单点登录的两种实现方式,附源码

最近工作有点忙&#xff0c;好久没更新文章了&#xff0c;正好这两天在整理单点登陆相关的文档&#xff0c;今天趁着小孩睡着了&#x1f92b;&#xff0c;赶紧码一篇实战文交差。 概念 单点登录&#xff08;Single Sign-On&#xff0c;SSO&#xff09;是一种身份验证服务&…

机器学习常识 13: PCA

摘要: 主成分分析 (principal component analysis, PCA) 是一种有理论依据的无监督特征提取的线性方法. 1. 特征选择与特征提取 特征选择是指从已有的特征里面选择出一个子集. 例如: 身高、体重、性别、年龄、体温、血相等等, 如果要一个人是否患流感&#xff0c;身高、体重等…

OpenMMLab-AI实战营第二期——1. 计算机视觉与OpenMMLab概述

文章目录 1. 课程内容概述1.1 Openmmlab框架1.2 课程其他说明 2. mmcv安装2.1 正确步骤2.2 debug2.3 错误探索 1. 课程内容概述 个人更关注语义分割和3D方面的内容&#xff0c;所以这里重点记录这两点相关的。 1.1 Openmmlab框架 具体的模块&#xff0c;详见&#xff1a;http…

wy的leetcode刷题记录_Day67

wy的leetcode刷题记录_Day67 声明 本文章的所有题目信息都来源于leetcode 如有侵权请联系我删掉! 时间&#xff1a;2023-6-1 前言 目录 wy的leetcode刷题记录_Day67声明前言1019. 链表中的下一个更大节点题目介绍思路代码收获 1019. 链表中的下一个更大节点 222. 完全二叉树…

UUOffice 工具箱,一款功能强大的 Excel 办公插件,好用推荐 ~

简介 UUOffice 工具箱,是一款功能强大的Office插件&#xff0c;功能强大&#xff0c;有着各种的单元格及文本的处理工具&#xff0c;自定义扩展函数&#xff0c;批注管理&#xff0c;图片导入导出&#xff0c;工作表汇总&#xff0c;联想输入等等超多实用工具&#xff0c;对日…

奇葩算法——猴子排序

&#x1f3c6;今日学习目标&#xff1a; &#x1f340;猴子排序 ✅创作者&#xff1a;林在闪闪发光 ⏰预计时间&#xff1a;30分钟 &#x1f389;个人主页&#xff1a;林在闪闪发光的个人主页 &#x1f341;林在闪闪发光的个人社区&#xff0c;欢迎你的加入: 林在闪闪发光的社区…

Docker下载遇到的报错以及解决记录

目录 一、docker介绍 1. Docker引擎 2. Docker镜像 3. Docker容器 4. Docker仓库 5. Docker网络 二、docker下载 1.首先再官方下载好docker 2.在我打开时出现了下面的错误&#xff1a; 然后我下载了一个wsl 然后就可以正常打开了 &#xff08;2&#xff09;如果自己的电…

「学习IT技术和编写高质量代码的经验和建议」

一、你在编写代码时&#xff0c;会特别注意哪些流程&#xff1f; 在编写代码的过程中&#xff0c;我通常会特别注意以下流程&#xff1a; 输入验证&#xff1a;确保输入的参数满足预期&#xff0c;防止出现非法输入导致的安全问题或异常错误。 异常处理&#xff1a;在代码中添…

迅为全国产ATX3A5000_7A2000主板-龙芯平台安装 开源loongnix系统

Loongnix下载 Loongnix桌面版镜像:有基于mate主题的版本和基于cartoon主题的版本。本章节的安装 步骤以cartoon主题的安装方式为例&#xff0c;mate主题的ISO安装步骤与cartoon主题的安装方式类 似。 1.1 引导和开始安装 主机启动后,BIOS从U盘引导启动系统&#xff0c;出现…

Vue组件化、通过自定义指令子组件向父组件传递、$nextTick

1.如何安装Vue脚手架&#xff1f; 第一步&#xff08;仅第一次执行&#xff09;&#xff1a;全局安装vue/clinpm install -g vue/cli 第二步&#xff1a;切换到你要创建项目的目录&#xff0c;然后使用命令创建项目vue create xxxx 第三步&#xff1a;启动项目npm run serve 2…

chatgpt赋能python:Python中的或且非

Python中的或且非 Python语言中的逻辑运算符包括&#xff1a;或、与、非&#xff0c;分别用 “|”、“&”、"~"符号表示。 或运算符&#xff08;|&#xff09; 当两个操作数中有一个为True时&#xff0c;结果为True。 例如&#xff1a; a 1 b 2 c 3 if a…

Qt概述和项目文件介绍

注意&#xff1a;学习本专栏的内容需要了解C相关知识&#xff0c;会涉及到C基础语法和相关特性&#xff0c;可以参考我的另一个专栏 c从零开始_小梁今天敲代码了吗的博客-CSDN博客 目录 一.什么是Qt 二.Qt的案例 三.项目文件介绍 一.什么是Qt 是一个跨平台的 C 应用程序…