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

Codeforces Round 1023 (Div.2)

比赛链接:CF1023

A. LRC and VIP

  • 如果 a a a 数组全部值都相同,则无法构造出满足条件的 B B B, C C C 序列。
  • 否则,将最大值放到 C C C 序列中,其余元素放到 B B B 序列中。

时间复杂度: O ( n ) O(n) O(n)

#include <bits/stdc++.h>
using namespace std;const int N = 105;
int n, a[N];void solve() {cin >> n;for (int i = 1; i <= n; i++) cin >> a[i];int maxm = 0, minm = INT_MAX;for (int i = 1; i <= n; i++)maxm = max(maxm, a[i]), minm = min(minm, a[i]);if (maxm == minm) {cout << "NO\n";return;}cout << "YES\n";for (int i = 1; i <= n; i++) cout << (1 + (a[i] == maxm)) << " ";cout << "\n";
}int main() {ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);int T;cin >> T;while (T--) solve();return 0;
}

B. Apples in Boxes

Jerry 获胜条件:

  • 当前最大值 − 1 - 1 1 后,剩余所有元素的最大值 − - 最小值 > k > k >k
  • 操作一次后,剩余所有元素数量的和为偶数。

剩余情况都是 Tom 获胜。

时间复杂度: O ( n ) O(n) O(n)

#include <bits/stdc++.h>
using namespace std;#define int long longconst int N = 1e5 + 10;
int n, k, a[N];void solve() {cin >> n >> k;int maxm = 0, minm = LLONG_MAX, sum = 0, maxpos = 0;for (int i = 1; i <= n; i++) {cin >> a[i];sum += a[i];if (a[i] > maxm) maxm = a[i], maxpos = i;}a[maxpos]--;maxm = 0, minm = LLONG_MAX;for (int i = 1; i <= n; i++)maxm = max(maxm, a[i]), minm = min(minm, a[i]);if (maxm - minm > k || sum % 2 == 0) cout << "Jerry\n";else cout << "Tom\n";
}signed main() {ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);int T;cin >> T;while (T--) solve();return 0;
}

C. Maximum Subarray Sum

  • 如果 s i s_i si 全为 1,无法进行操作,利用 d p dp dp 找出最大连续子数组,并且判断是否等于 k k k
  • 如果存在 s i = 0 s_i = 0 si=0,根据题目数据范围,只需要一个位置就可以让最大连续子数组的值等于 k k k
    • 找到第一个 s i = 0 s_i = 0 si=0 的位置,算出这个位置前面的一段最大后缀 s u f suf suf,跟这个位置往后的最大前缀 p r e pre pre,这个位置的 a i a_i ai 直接赋值为 k − p r e − s u f k - pre - suf kpresuf
    • 第二个 s i = 0 s_i = 0 si=0 的位置,将 a i a_i ai 赋值为 − 1 0 18 -10^{18} 1018,其余位置不需要改变。

时间复杂度: O ( n ) O(n) O(n)

#include <bits/stdc++.h>
using namespace std;#define int long longconst int N = 2e5 + 10;
int n, k, a[N], dp[N];
string s;void solve() {cin >> n >> k >> s;s = " " + s;for (int i = 1; i <= n; i++) cin >> a[i];int pos1 = 0;for (int i = 1; i <= n; i++) {if (s[i] == '0') {pos1 = i;break;}}if (pos1 == 0) {int maxm = 0;for (int i = 1; i <= n; i++)dp[i] = max(dp[i - 1] + a[i], a[i]), maxm = max(maxm, dp[i]);if (maxm == k) {cout << "Yes\n";for (int i = 1; i <= n; i++) cout << a[i] << " ";cout << "\n";} else cout << "No\n";return;}int maxm = 0, r = 1;for (int i = 1; i <= n; i++) dp[i] = 0;for (int l = 1; l <= n; l++) {r = l;while (r <= n && s[r] != '0') {dp[r] = max(dp[r - 1] + a[r], a[r]);maxm = max(maxm, dp[r]);r++;}l = r;}if (maxm > k) {cout << "No\n";return;}int sum = 0, pre = 0, suf = 0;for (int i = pos1 - 1; i >= 1; i--) {sum += a[i];pre = max(pre, sum);}sum = suf = 0;int pos2 = 0, pos = pos1;for (int i = pos1 + 1; i <= n; i++) {sum += a[i];if (suf < sum) {pos = i;suf = sum;}if (s[i] == '0') {pos2 = i;break;}}a[pos1] = k - suf - pre;if (pos2) {for (int i = pos + 1; i <= n; i++) {if (s[i] == '0') a[i] = -1e18;}}cout << "Yes\n";for (int i = 1; i <= n; i++) cout << a[i] << " ";cout << "\n";
}signed main() {ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);int T;cin >> T;while (T--) solve();return 0;
}

D. Apple Tree Traversing

可以发现按照字典序排列的第一关键字是 d d d,也就是路径长度,所以只需要每一次在剩余森林的每一棵树中找出直径,并且存下这条直径的长度以及端点,最后按照字典序排列即可。

时间复杂度: O ( n n ) O(n \sqrt{n}) O(nn )

  • 每一次找的直径一定会比前面的短,所以最多需要找 n \sqrt{n} n 次直径。
#include <bits/stdc++.h>
using namespace std;const int N = 150005;
int n, pre[N], used[N], d[N], head[N], num = 0, tar;
struct edge { int to, nxt; } e[N << 1];
array<int, 3> ans[N];inline int read() {int x = 0, f = 1; char c = getchar();while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();return x * f;
}void addEdge(int u, int v) { e[++num] = (edge){ v, head[u] }, head[u] = num; }void dfs(int u, int fa) {for (int i = head[u]; i; i = e[i].nxt) {int v = e[i].to;if (v == fa || used[v]) continue;d[v] = d[u] + 1, pre[v] = u;if (d[v] > d[tar] || (d[v] == d[tar] && tar < v)) tar = v;dfs(v, u);}
}void solve() {n = read();for (int i = 1; i <= n; i++) head[i] = used[i] = 0;num = 0;for (int i = 1; i < n; i++) {int u = read(), v = read();addEdge(u, v), addEdge(v, u);}int m = 0;tar = 0;while (1) {int flag = 0;for (int i = 1; i <= n; i++)if (!used[i]) { flag = i; break; }if (!flag) break;d[flag] = 1;tar = flag;dfs(tar, 0);int st = tar;d[tar] = 1;dfs(tar, 0);int ed = tar;for (int i = ed; i != st; i = pre[i]) used[i] = 1;used[st] = 1;ans[++m] = array<int, 3>({ d[ed], max(st, ed), min(st, ed) });}sort(ans + 1, ans + m + 1, greater<array<int, 3>>());for (int i = 1; i <= m; i++) printf("%d %d %d ", ans[i][0], ans[i][1], ans[i][2]);putchar('\n');
}int main() {// freopen("D.out", "w", stdout);int T = read();while (T--) solve();return 0;
}

E. Ain and Apple Tree

  • 可以发现,当构造出来的树是一条链的时候答案最大,答案为 ∑ i = 0 n − 1 i ⋅ ( n − i − 1 ) \sum_{i = 0}^{n - 1}i \cdot (n - i - 1) i=0n1i(ni1)
    • 如果 k > ∑ i = 0 n − 1 i ⋅ ( n − i − 1 ) + 1 k > \sum_{i = 0}^{n - 1}i \cdot (n - i - 1) + 1 k>i=0n1i(ni1)+1,则无解。
  • 将一条链状的树的最深节点往上移到比其深度小 x x x 的节点的地方时,最后答案会减小 1 + 2 + … + x − 1 = x ( x − 1 ) 2 1 + 2 + \ldots + x - 1 = \frac{x(x - 1)}{2} 1+2++x1=2x(x1)
  • 我们可以将要构造的树初始化为链状,然后将最深节点依次上移,直到 ∣ ∑ i = 1 n ∑ j = i + 1 n d e p ( l c a ( i , j ) ) − k ∣ < 1 |\sum_{i = 1}^n\sum_{j = i + 1}^ndep(lca(i, j)) - k| < 1 i=1nj=i+1ndep(lca(i,j))k<1

时间复杂度: O ( n ) O(n) O(n)

#include <bits/stdc++.h>
using namespace std;#define int long long int n, k;void solve() {cin >> n >> k;int maxm = 0;for (int i = 0; i < n; i++) maxm += i * (n - i - 1);if (maxm < k - 1) {cout << "No\n";return;}k = maxm - k;vector<vector<int>> g(n + 1);int h = n - 1;for (int i = n - 1; i; i--)if (k >= i * (i - 1) / 2) {g[h - i].push_back(h);h--;k -= i * (i - 1) / 2;}for (int i = 0; i < h; i++) g[i].push_back(i + 1);cout << "Yes\n";for (int i = 0; i < n; i++) {for (int v : g[i]) cout << i + 1 << " " << v + 1 << "\n"; }
}signed main() {ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);int T;cin >> T;while (T--) solve();return 0;
}

F1. Cycling (Easy Version)

  • a [ x , y ) > = a y + 1 a_{[x,y)} >= a_y + 1 a[x,y)>=ay+1 时,每次将 y y y 前移一定不会使答案更劣,因为这种操作的花费为 a y + 1 a_y + 1 ay+1,其中 1 1 1 是前移的花费。
  • 如果 a y a_y ay 要后移到位置 z z z,Leo 超越到位置 x x x 的花费为 c o s t [ z + 1 , n ] + ( z − y ) ⋅ a y + ( z − y ) + ( z − x − 1 ) cost_{[z + 1, n]} + (z - y) \cdot a_y + (z - y) + (z - x - 1) cost[z+1,n]+(zy)ay+(zy)+(zx1)

时间复杂度: O ( n 2 ) O(n^2) O(n2)

#include <bits/stdc++.h>
using namespace std;#define int long longconst int N = 5e3 + 10;
int n, a[N], dp[N];void solve() {cin >> n;for (int i = 1; i <= n; i++) cin >> a[i], dp[i - 1] = LLONG_MAX;dp[n] = 0;for (int i = n - 1; i >= 0; i--) {int p = i + 1;for (int j = i + 1; j <= n; j++)if (a[j] < a[p]) p = j;for (int j = p; j <= n; j++)dp[i] = min(dp[i], dp[j] + 2 * (j - p) + (j - i) * a[p] + p - i - 1);}cout << dp[0] << "\n";
}signed main() {ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);int T;cin >> T;while (T--) solve();return 0;
}

时间复杂度: O ( n 2 ) O(n^2) O(n2)

http://www.dtcms.com/a/192691.html

相关文章:

  • JAVA学习-练习试用Java实现“语音识别的基础 :如使用MFCC特征提取和简单的分类器”
  • 【AI论文】对抗性后期训练快速文本到音频生成
  • stm32使用freertos时延时时间间隔不对,可能是晶振频率没设置
  • 【Redis】压缩列表
  • Oracle统计信息收集时的锁持有阶段
  • UDP 多点通信
  • 高频交直流电流测量技术:射频PA与MEMS测试的简单解决方案
  • Buildroot 移植MiniGUI
  • Python高级进阶:Vim与Vi使用指南
  • 多模态大语言模型arxiv论文略读(七十七)
  • 一站式本地化方案,解决欧洲反向海淘多重难题
  • 【Linux】网络基础与socket编程基础
  • 【中级软件设计师】网络攻击(附软考真题)
  • [Harmony]大文件持久化
  • Spring Boot多数据源配置的陷阱与终极解决方案
  • 2025 年十大网络安全预测
  • 【问题记录】08 MAC电脑,安装HP打印机驱动,提示:此更新需要macOS版本15.0或更低版本
  • 汽车零部件冲压车间MES一体机解决方案
  • CAPL编程系列_04
  • Linux线程互斥锁
  • 【C++】set和multiset的常用接口详解
  • AWS Elastic Beanstalk控制台部署Spring极简工程
  • 【Java ee】关于抓包软件Fiddler Classic的安装与使用
  • React 第四十一节Router 中 useActionData 使用方法案例以及注意事项
  • 观测云产品更新 | 安全监测、事件中心、仪表板AI智能分析等
  • 唐婉歆携作品VoyEase亮相2025米兰设计周,以多感官沉浸式设计重塑全球旅行体验
  • 2025年5月AI科技领域周报(5.5-5.11):AGI研究进入关键验证期 具身智能开启物理世界交互新范式
  • 数据可视化-----子图的绘制及坐标轴的共享
  • Linux的进程管理和用户管理
  • C++ Mac 打包运行方案(cmake)