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

2024icpc南京站

2024 i c p c 南京站 \Huge{2024icpc南京站} 2024icpc南京站

文章目录

  • C. Primitive Root
    • 题意
    • 思路
    • 标程
  • F. Equivalent Rewriting
    • 题意
    • 思路
    • 标程
  • G. Knapsack
    • 题意
    • 思路
    • 标程
  • I. Counter
    • 题意
    • 思路
    • 标程

比赛地址:The 2023 ICPC Asia Nanjing Regional Contest (The 2nd Universal Cup. Stage 11: Nanjing)

官方题解:2023 ICPC 亚洲区域赛南京站 - SUA Wiki

C. Primitive Root

题意

给定质数 P P P和非负整数 m m m,有多少非负整数 g g g满足$ g≤m ~&&~ g⊕(P−1)≡1 (mod P)$?这里 ⊕ ⊕ 是按位异或(XOR) 运算符。

思路

跟据题目给出的公式,我们可以做以下变形:
g ⊕ ( P − 1 ) ≡ 1 ( m o d P ) g ⊕ ( P − 1 ) = k P + 1 g = ( k P + 1 ) ⊕ ( P − 1 ) ≤ m ( k P + 1 ) + ( P − 1 ) ≤ m ( k + 1 ) p ≤ m g\oplus(P-1)\equiv1(mod~P)\\ g\oplus(P-1)=kP+1\\ g=(kP+1)\oplus (P-1)~~\le m\\ (kP+1)+(P-1)\le m\\ (k+1)p\le m\\ g(P1)1(mod P)g(P1)=kP+1g=(kP+1)(P1)  m(kP+1)+(P1)m(k+1)pm
那么对于区间 0 ≤ k ≤ ⌊ m p ⌋ − 1 0\le k \le \left \lfloor \frac{m}{p} \right \rfloor - 1 0kpm1,均有$ (kP+1)+(P-1)\le (k+1)P \le m$,满足要求。

对于所有 k ≤ ⌈ m P ⌉ + 1 k \le \left \lceil \frac{m}{P} \right \rceil + 1 kPm+1,均有$ (kP+1)+(P-1)\ge (k-1)P + 2 \le m$,不满足要求。

因此我们只需要检查区间 ⌊ m p ⌋ ≤ k ≤ ⌈ m p ⌉ \left \lfloor \frac{m}{p} \right \rfloor \le k \le \left \lceil \frac{m}{p} \right \rceil pmkpm的值即可。

标程

#define int long long 
using namespace std;
void solve() {int p,m;cin >> p >> m;int ans = (m/p);
//	cout << ans << endl;for(int i = m/p; i <= m / p +1; i ++)if(((1 + i * p) ^ (p-1)) <= m)ans++;cout << ans << endl; 
}

F. Equivalent Rewriting

题意

题目首先给出两个数字n,m,分别表示操作次数和数组长度。然后下列操作是对数组进行操作。

  • p a 1 a 2 a 3 . . . a p p~a_1~a_2~a_3~...~a_p p a1 a2 a3 ... ap

若当前为第 i i i次操作,那么该操作为将数组中 a 1 , a 2 , a 3 , . . . , a p a_1,a_2,a_3,...,a_p a1,a2,a3,...,ap全部变为 i i i

经过若干次这样的操作之后,得到数组的最后状态。题目要求能够改变操作的顺序,使得最终数组的结果不变。

思路

本题需要考虑是否存在某一个操作可以改变顺序。我们可以发现,当前操作结果可能会被后续操作覆盖,并且分为三种情况:

  • 当前的操作结果会部分被后续操作影响。
  • 当前的操作结果会全部被后续操作。
  • 当前的操作结果不会被后续操作影响。

特别地对于后两种情况,可以分开讨论:

  • 某一次操作不会收到后续操作的影响,可将其放置在其后任意一个位置(最后一次操作除外)。
  • 某一次操作会被后续操作全部覆盖,那么可将其放置在其前面任意一个位置(第一次操作除外)。

事实上由于是可以选任意位置,我们只需要将其与相邻位置交换即可。

标程

#define int long long
void solve() {int n, m; cin >> n >> m;vector<vector<int>> op(n + 1);for(int i = 1; i <= n; i ++ ) {int x; cin >> x;while(x -- ) {int pos; cin >> pos;op[i].push_back(pos);}}vector<bool> st(m + 1);vector<int> cnt(m + 1);for(auto t : op[n]) cnt[t] ++ ;bool flag = false;for(int i = n - 1; i >= 1; i -- ) {bool flag = true;for(auto t : op[i]) {if(st[t]) continue;cnt[t] ++ ;if(cnt[t] > 1) flag = false;}for(auto t : op[i + 1]) {if(st[t]) continue;cnt[t] -- ; st[t] = true;}if(flag) {cout << "Yes\n";for (int j = 1; j <= i - 1; j ++ ) cout << j << ' ';cout << i + 1 << ' ' << i;for (int j = i + 2; j <= n; j ++ ) cout << ' ' << j;cout << '\n';return;}}cout << "No\n";
}

G. Knapsack

题意

给定 n n n件物品的体积 w i w_i wi与价值 v i v_i vi,以及背包的总容量 W W W

你可以优先选择 k k k件物品获得他们的价值,随后再选择一些物品,要求随后选择的物品的体积之和不超过` W W W

最大化选择物品的价值之和。

思路

注意到一定存在一个最优选法同时满足以下两个条件:

  1. 如果存在物品 a , b a,b a,b满足 𝑎 被免费选走, b b b被付费选走,那么 w a ≥ w b w_a \ge w_b wawb。否则我们可以改成免费选 b b b,付费选 a a a,方案不会变劣。
  2. 如果存在物品 a , b a,b a,b满足 a a a被免费选走, b b b没有被选走,那么 v a ≥ v b v_a \ge v_b vavb。否则我们可以改成免费选 b b b,不选择 a a a,方案不会变劣。

因此,如果我们将所有物品按照 w i w_i wi从小到大排序,那么对于最优策略而言,一定存在一个分界点 M M M,满足 i > M i>M i>M的物品中,价值前 k k k大的物品被免费选走。

对于每个 i i i,可以通过维护一个堆来预处理出从第 i i i个物品开始的后缀免费选出 k k k个物品的最大价值之和。

因此我们只需要对每个前缀维护出 0/1 背包的结果即可。复杂度 O ( n w + n k + n l o g n ) O(nw+nk+nlogn) O(nw+nk+nlogn)

标程

#define int long long 
#define PII pair<int, int>
#define fi first 
#define se secondconst int INF = 0x7fffffff;void Solved() {int n, w, k; cin >> n >> w >> k;vector<PII> a(n);vector<int> f(w + 1), g(n + 1);// f[i]:计算背包问题的滚动数组// g[i]:从第 i 个物品开始的后缀免费选出 K 个物品的最大价值之和priority_queue<int, vector<int>, greater<int>> q;for(auto &[i, j] : a) cin >> i >> j;sort(ALL(a));int sum = 0;g[n] = 0;// 计算出后缀选出的免费物品的最大价值之和for(int i = n - 1; i >= 0; i -- ) {q.push(a[i].se);sum += a[i].se;if(q.size() > k) {sum -= q.top();q.pop();}g[i] = sum;}for(int i = 0; i <= w; i ++ ) f[i] = -INF;f[0] = 0;int res = g[0]; // 结果初值,只买免费物品// 01背包模板for(int i = 0; i < n; i ++ ) {for(int j = w; j >= a[i].fi; j -- ) {f[j] = max(f[j], f[j - a[i].fi] + a[i].se);res = max(res, f[j] + g[i + 1]);    // 计算在分界点i时的情况}}cout << res << endl;
}

I. Counter

题意

有一个计数器,一开始是0,有两种操作,每次操作可以把值+1或清零。

给若干已知条件表示第 x i x_i xi次操作后计数器的值为 v i v_i vi,问是否有一种操作序列满足所有的已知条件。

思路

根据题目的性质,对于已知的操作,分为两种情况:计数器的值是否为0。

同时可以发现,对于某一次操作,若 v i = 5 v_i=5 vi=5,那么 x i x_i xi前(包括 x i x_i xi)会有连续5次的+1操作。

那么,若已知的操作中有不符合上述情况的,这个操作序列肯定就不合法。因此可以按照 x i x_i xi排序,然后从后向前遍历。

遍历过程中标记当前位置的+1操作是从哪个位置开始的,然后遍历过程中对于不合法的情况就直接结束即可,对于不合法的情况:

  • v i = 0 v_i=0 vi=0
    • x i > x x_i>x xi>x
  • v i ! = 0 v_i!=0 vi!=0
    • x i = t x_i=t xi=t
    • x i > t & & v i ! = x i − t x_i>t ~~~\&\&~~~ v_i!=x_i-t xi>t   &&   vi!=xit
    • 否则为合法,更新标记位置 t t t

标程

#define PII pair<int,int>
#define pb push_back
#define fi first
#define se secondvoid solve() {int n, m; cin >> n >> m;vector<PII> v(m);for(auto &[i, j] : v) cin >> i >> j;sort(v.begin(), v.end());int x = n + 1;for(int i = m - 1; i >= 0; i -- ) {if(v[i].se == 0) {if(v[i].fi > x) {cout << "No\n"; return;}} else {if(v[i].fi == x) {cout << "No\n"; return;}else if(v[i].fi > x) {if(v[i].se != v[i].fi - x) {cout << "No\n"; return;}} else {x = v[i].fi - v[i].se;if(x < 0) {cout << "No\n"; return;}}}}cout << "Yes\n";
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • go-zero的快速实战(完整)
  • 基础 Web 开发
  • R134a制冷剂简介
  • clickhouse适用的业务场景
  • 编写XBOX控制器实现鼠标键盘输入
  • 数学建模笔记—— 回归分析
  • MultiSnapRecyclerView:让Android RecyclerView的滚动停靠更灵活
  • oracle 用游标为什么会比for循环慢?
  • 开始一个WPF项目时的记忆重载入
  • [创业之路-148] :ToC与ToB产品研发的比较
  • git解决同时编辑一个文件的冲突
  • MySQL数据的增删改查(一)
  • CGAL and the Boost Graph Library
  • 就服务器而言,ARM架构与X86架构有什么区别?各自的优势在哪里?
  • oracle select字段有子查询会每次执行子查询吗
  • 【node学习】协程
  • chrome扩展demo1-小时钟
  • JDK 6和JDK 7中的substring()方法
  • vue脚手架vue-cli
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 爱情 北京女病人
  • 给初学者:JavaScript 中数组操作注意点
  • 利用DataURL技术在网页上显示图片
  • 聊聊redis的数据结构的应用
  • 猫头鹰的深夜翻译:JDK9 NotNullOrElse方法
  • 腾讯大梁:DevOps最后一棒,有效构建海量运营的持续反馈能力
  • 小而合理的前端理论:rscss和rsjs
  • ​Distil-Whisper:比Whisper快6倍,体积小50%的语音识别模型
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • ​十个常见的 Python 脚本 (详细介绍 + 代码举例)
  • (27)4.8 习题课
  • (zz)子曾经曰过:先有司,赦小过,举贤才
  • (二)linux使用docker容器运行mysql
  • (附源码)spring boot校园健康监测管理系统 毕业设计 151047
  • (附源码)ssm高校社团管理系统 毕业设计 234162
  • (附源码)ssm学生管理系统 毕业设计 141543
  • (三)uboot源码分析
  • (四)c52学习之旅-流水LED灯
  • (一)80c52学习之旅-起始篇
  • ****Linux下Mysql的安装和配置
  • .NET Entity FrameWork 总结 ,在项目中用处个人感觉不大。适合初级用用,不涉及到与数据库通信。
  • .NET Framework 服务实现监控可观测性最佳实践
  • .NET 中让 Task 支持带超时的异步等待
  • .net实现客户区延伸至至非客户区
  • .NET序列化 serializable,反序列化
  • .pings勒索病毒的威胁:如何应对.pings勒索病毒的突袭?
  • [ C++ ] STL---string类的使用指南
  • [100天算法】-目标和(day 79)
  • [15] 使用Opencv_CUDA 模块实现基本计算机视觉程序
  • [23] 4K4D: Real-Time 4D View Synthesis at 4K Resolution
  • [④ADRV902x]: Digital Filter Configuration(发射端)
  • [Android]RecyclerView添加HeaderView出现宽度问题
  • [BIZ] - 1.金融交易系统特点
  • [C++]命名空间等——喵喵要吃C嘎嘎
  • [COI2007] Sabor