VP Educational Codeforces Round 24

news/2025/3/5 19:07:05/文章来源:https://www.cnblogs.com/maburb/p/18753333

A. Diplomas and Certificates

点击查看代码
void solve() {i64 n, k;std::cin >> n >> k;i64 cnt = (n / 2) / (k + 1) * k;std::cout << cnt / k << " " << cnt << " " << n - cnt - cnt / k << "\n";
}

B. Permutation Game

题意:\(n\)个人围成一个圈,如果第\(i\)个人是领导者,那么下一个领导者是顺时针走\(a_i\)个位置。其中\(a\)是一个排列。选择给出\(m\)轮的领导者,求\(a\)

可以通过\(l_{i+1} - l_i\)得出\(a_i\),检查有没有冲突和重复,没有出现过的随便填没用过的数。

点击查看代码
void solve() {int n, m;std::cin >> n >> m;std::vector<int> l(m + 1);for (int i = 1; i <= m; ++ i) {std::cin >> l[i];}std::vector<int> a(n + 1);std::set<int> s;for (int i = 1; i <= n; ++ i) {s.insert(i);}for (int i = 1; i + 1 <= m; ++ i) {int t = (l[i + 1] - l[i] + n) % n;if (t == 0) {t = n;}if (a[l[i]] == 0) {if (!s.count(t)) {std::cout << -1 << "\n";return;}s.erase(t);a[l[i]] = t;} else if (a[l[i]] != t) {std::cout << -1 << "\n";return;}}for (int i = 1; i <= n; ++ i) {if (a[i] == 0) {a[i] = *s.begin();s.erase(s.begin());}}for (int i = 1; i <= n; ++ i) {std::cout << a[i] << " \n"[i == n];}
}

C. Sofa Thief

题意:\(n\)个沙发,每个沙发有两个坐标,对于\(i, j\),如果\(j\)有一个横坐标小于\(i\)的一个横坐标,则\(j\)\(i\)的左边。如果\(j\)有一个横坐标大于\(i\)的一个横坐标,则\(j\)\(i\)的右边。如果\(j\)有一个纵坐标小于\(i\)的一个纵坐标,则\(j\)\(i\)的上边。如果\(j\)有一个纵坐标大于\(i\)的一个纵坐标,则\(j\)\(i\)的下边。
求有没有一个沙发的左边有\(cnt_l\)个沙发,右边有\(cnt_r\)个沙发,上面有\(cnt_t\)个沙发,下面有\(cnt_d\)个沙发。

给每个坐标从小到大从大到小排序模拟,求出每个沙发各个方向有多少沙发。

点击查看代码
void solve() {int k, n, m, L, R, T, D;std::cin >> k >> n >> m;std::vector<std::array<int, 3>> a;for (int i = 0; i < k; ++ i) {int x1, y1, x2, y2;std::cin >> x1 >> y1 >> x2 >> y2;a.push_back({x1, y1, i});a.push_back({x2, y2, i});}std::cin >> L >> R >> T >> D;std::vector<int> l(k, -1), r(k, -1), t(k, -1), d(k, -1);std::sort(a.begin(), a.end());std::set<int> s;for (int i = 0; i < a.size(); ++ i) {int j = i;while (j + 1 < a.size() && a[j + 1][0] == a[i][0]) {++ j;}for (int x = i; x <= j; ++ x) {l[a[x][2]] = (int)s.size() - s.count(a[x][2]);}for (int x = i; x <= j; ++ x) {s.insert(a[x][2]);}i = j;}s.clear();std::sort(a.begin(), a.end(), std::greater<>());for (int i = 0; i < a.size(); ++ i) {int j = i;while (j + 1 < a.size() && a[j + 1][0] == a[i][0]) {++ j;}for (int x = i; x <= j; ++ x) {r[a[x][2]] = (int)s.size() - s.count(a[x][2]);}for (int x = i; x <= j; ++ x) {s.insert(a[x][2]);}i = j;}s.clear();std::sort(a.begin(), a.end(), [&](std::array<int, 3> & a, std::array<int, 3> & b) {return a[1] > b[1];});for (int i = 0; i < a.size(); ++ i) {int j = i;while (j + 1 < a.size() && a[j + 1][1] == a[i][1]) {++ j;}for (int x = i; x <= j; ++ x) {d[a[x][2]] = (int)s.size() - s.count(a[x][2]);}for (int x = i; x <= j; ++ x) {s.insert(a[x][2]);}i = j;}s.clear();std::sort(a.begin(), a.end(), [&](std::array<int, 3> & a, std::array<int, 3> & b) {return a[1] < b[1];});for (int i = 0; i < a.size(); ++ i) {int j = i;while (j + 1 < a.size() && a[j + 1][1] == a[i][1]) {++ j;}for (int x = i; x <= j; ++ x) {t[a[x][2]] = (int)s.size() - s.count(a[x][2]);}for (int x = i; x <= j; ++ x) {s.insert(a[x][2]);}i = j;}s.clear();for (int i = 0; i < k; ++ i) {// std::cout << l[i] << " " << r[i] << " " << t[i] << " " << d[i] << "\n";if (l[i] == L && r[i] == R && t[i] == T && d[i] == D) {std::cout << i + 1 << "\n";return;}}std::cout << -1 << "\n";
}

D. Multicolored Cars

题意:有一个数组,\(cntx_i\)\(x\)这个数在\(1\)\(i\)出现的次数。现在\(Alcie\)选了一个\(A\),你要选一个\(B\),使得对于任意一个\(i\)都有\(cntB_i \geq cntA_i\)

\(set\)存每个数的出现次数,然后从前往后更新\(cnt\),同时更新\(set\)。然后每次把小于\(cntA_i\)的位置都删掉。每次二分是\(log\)的,而每个数只会被删一次,总共是\(O(n)\)的,所以时间复杂度是\(O(nlogV)\)\(V\)是值域。

点击查看代码
void solve() {int n, A;std::cin >> n >> A;std::vector<int> a(n);for (int i = 0; i < n; ++ i) {std::cin >> a[i];}std::set<std::pair<int, int>> s;for (int i = 1; i <= 1000000; ++ i) {s.insert({0, i});}std::vector<int> cnt(1000010);for (auto & c : a) {if (s.count({cnt[c], c})) {s.erase({cnt[c], c});++ cnt[c];s.insert({cnt[c], c});}auto it = s.lower_bound({cnt[A], 0});s.erase(s.begin(), it);}s.erase({cnt[A], A});if (s.empty()) {std::cout << -1 << "\n";} else {std::cout << s.begin()->second << "\n";}
}

E. Card Game Again

题意:求有多少区间的乘积和是\(k\)的倍数。

\(k\)质因数分解,得到\(m\)个质数及其个数,然后记\(sum[i][j]\)\([1, i]\)里第\(j\)个质数出现的次数。那么我们枚举右端点,二分合法的最右边的左端点。

点击查看代码
void solve() {int n, k;std::cin >> n >> k;std::vector<int> a(n + 1);for (int i = 1; i <= n; ++ i) {std::cin >> a[i];}std::map<int, int> mp;for (int i = 2; i <= k / i; ++ i) {if (k % i == 0) {while (k % i == 0) {++ mp[i];k /= i;}}}if (k > 1) {++ mp[k];}std::vector<int> sumk;std::vector<int> b;for (auto & [x, cnt] : mp) {b.push_back(x);sumk.push_back(cnt);}int m = (int)b.size();std::vector sum(n + 1, std::vector<int>(m));for (int i = 1; i <= n; ++ i) {sum[i] = sum[i - 1];for (int j = 0; j < m; ++ j) {int cnt = 0;while (a[i] % b[j] == 0) {++ cnt;a[i] /= b[j];}sum[i][j] += cnt;}}auto check = [&](int l, int r) -> bool {for (int i = 0; i < m; ++ i) {if (sum[r][i] - sum[l - 1][i] < sumk[i]) {return false;}}return true;};i64 ans = 0;for (int i = 1; i <= n; ++ i) {int l = 1, r = i;while (l < r) {int mid = l + r + 1 >> 1;if (check(mid, i)) {l = mid;} else {r = mid - 1;}}if (!check(l, i)) {l = 0;}ans += l;}std::cout << ans << "\n";
}

F. Level Generation

待补


G. Four Melodies

题意:在一个数组种选四个不相交的子序列,每个子序列相邻的两个数要么相差1,要么余7相同。使得四个子序列长度加起来最大。

本质是在一个图里选\(k\)条路径使得路径和最大的问题。
如果我们向每个\(|a_i - a_j| = 1\)\(a_i \equiv a_j \pmod{7}\)\((i, j)\)\(i\)\(j\)连边。那么就等价于求图里的两段路径,使得路径长度之和最大,这是个经典费用流问题。我们把每个点拆成出度和入度,一个点的入度向出度连费用为1流量为1的边,可以连边的由出度向入度连费用为0流量为1的边,同时源点给每个点的入度连费用为0流量为1的边,每个点的出度向汇点连费用为0流量为1的边,然后为了满足两条路径的需求,超级源点向源点连费用为0流量为2的边,汇点向超级汇点连费用为0流量为4的边。但这样边数太大,时间复杂度不能接受。
我们可以对于每个\(i\)的出度,往右边最近的\(a_i - a_j = 1\)以及\(a_i - a_j = -1\)\(j\)的入度连边,因为满足条件的\(a_j\)值只有两种,我们选最近的可以给后面留出更大空间,显然更优。然后对于\(a_i \equiv a_j \pmod{7}\)的最近的\(j\),我们由\(i\)的出度向\(j\)的入度连边,同时\(i\)的入度向\(j\)的入度连边,这意味着选了\(i\)可以继续选\(j\),或者如果不选\(i\)下一个就可以选\(j\)。这样就解决了。
这个问题可以由\(4\)条路径扩展成\(k\)条路径,只需要该超级源点和超级汇点与源点汇点之间的流量。

点击查看代码
template<class T>
struct MinCostFlow {struct _Edge {int to;T cap;T cost;_Edge(int to_, T cap_, T cost_) : to(to_), cap(cap_), cost(cost_) {}};int n;std::vector<_Edge> e;std::vector<std::vector<int>> g;std::vector<T> h, dis;std::vector<int> pre;bool dijkstra(int s, int t) {dis.assign(n, std::numeric_limits<T>::max());pre.assign(n, -1);std::priority_queue<std::pair<T, int>, std::vector<std::pair<T, int>>, std::greater<std::pair<T, int>>> que;dis[s] = 0;que.emplace(0, s);while (!que.empty()) {T d = que.top().first;int u = que.top().second;que.pop();if (dis[u] != d) {continue;}for (int i : g[u]) {int v = e[i].to;T cap = e[i].cap;T cost = e[i].cost;if (cap > 0 && dis[v] > d + h[u] - h[v] + cost) {dis[v] = d + h[u] - h[v] + cost;pre[v] = i;que.emplace(dis[v], v);}}}return dis[t] != std::numeric_limits<T>::max();}MinCostFlow() {}MinCostFlow(int n_) {init(n_);}void init(int n_) {n = n_;e.clear();g.assign(n, {});}void addEdge(int u, int v, T cap, T cost) {g[u].push_back(e.size());e.emplace_back(v, cap, cost);g[v].push_back(e.size());e.emplace_back(u, 0, -cost);}std::pair<T, T> flow(int s, int t) {T flow = 0;T cost = 0;h.assign(n, 0);while (dijkstra(s, t)) {for (int i = 0; i < n; ++i) {h[i] += dis[i];}T aug = std::numeric_limits<int>::max();for (int i = t; i != s; i = e[pre[i] ^ 1].to) {aug = std::min(aug, e[pre[i]].cap);}for (int i = t; i != s; i = e[pre[i] ^ 1].to) {e[pre[i]].cap -= aug;e[pre[i] ^ 1].cap += aug;}flow += aug;cost += aug * h[t];}return std::make_pair(flow, cost);}struct Edge {int from;int to;T cap;T cost;T flow;};std::vector<Edge> edges() {std::vector<Edge> a;for (int i = 0; i < e.size(); i += 2) {Edge x;x.from = e[i + 1].to;x.to = e[i].to;x.cap = e[i].cap + e[i + 1].cap;x.cost = e[i].cost;x.flow = e[i + 1].cap;a.push_back(x);}return a;}
};void solve() {int n;std::cin >> n;std::vector<int> a(n);for (int i = 0; i < n; ++ i) {std::cin >> a[i];}MinCostFlow<int> mf(2 * n + 4);int s = 2 * n, t = 2 * n + 1, S = 2 * n + 2, T = 2 * n + 3;mf.addEdge(S, s, 4, 0);mf.addEdge(t, T, 4, 0);for (int i = 0; i < n; ++ i) {mf.addEdge(s, i, 1, 0);mf.addEdge(i + n, t, 1, 0);mf.addEdge(i, i + n, 1, -1);for (int j = i + 1; j < n; ++ j) {if (a[i] == a[j] + 1) {mf.addEdge(i + n, j, 1, 0);break;}}for (int j = i + 1; j < n; ++ j) {if (a[i] == a[j] - 1) {mf.addEdge(i + n, j, 1, 0);break;}}for (int j = i + 1; j < n; ++ j) {if (a[i] % 7 == a[j] % 7) {mf.addEdge(i + n, j, 1, 0);mf.addEdge(i, j, 1, 0);break;}}}std::cout << -mf.flow(S, T).second << "\n";
}

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

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

相关文章

推荐三本数学方面的书籍《数学要素》、《矩阵力量》和《统计至简》 - 鸢尾花书:从加减乘除到机器学习 - 姜伟生 - PDF免费下载

下载地址:https://pdfs.top/book/鸢尾花书系列:从加减乘除到机器学习.html。《鸢尾花书系列:从加减乘除到机器学习》是姜伟生博士编写的机器学习从入门到精通合集,旨在帮助读者从编程基础到机器学习掌握关键技能。每本书内容简洁,适合不同阶段的学习者,帮助读者快速上手并…

第一次个人编程项目

学号 3123004294Github仓库链接 https://github.com/Berluga/3123004294.git项目 内容这个作业属于哪个课程 软件工程导论这个作业要求在哪里 作业要求文档这个作业的目标 通过实现一个查重系统,综合训练算法设计、工程规范、测试及文档撰写能力PSP 2.1 表格PSP阶段 预估耗时(…

【Java 开发】windows 命令行cmd界面,运行java 程序报错情况分析和解决!

windows cmd 运行java 程序报错了 (编译通过,运行报错)通过 java 和 javac 命令 得知,两个命令的版本不一样。因为这是因为有两个java 版本所导致的。 此时 需修改环境变量的配置。 此时我们找到 path 环境变量的配置 可以看到 配置了两个 JAVA_HOME的变量 一个JAVA_HOME 对…

2025/3/4 - Vue3学习--基础创建教程学习笔记

基于VUE创建:创建流程VScode实例-->编写APP组件

sql(3)多表查询

1.内连接查询(交集)2.外连接左外连接会全显示表一,右外连接会全显示表二,然后都显示交集部分。 3.子查询(嵌套查询) 行子查询表子查询注:给表起别名 select * from tb_emp e,tb_dept d where e.dept_id=d.id;

EndNote 21软件下载与安装教程

1、安装包 扫描下方二维码关注「软知社」,后台回复【042】三位数字即可免费获取分享链接,无广告拒绝套路;2、安装教程双击Setup.exe安装,弹窗安装对话框点击Next选择I would like a free ftrial ,点击Next点击Next选择I accept ,点击Next默认Next选择安装路径,建议C盘之外…

AxMath 2.6软件下载与安装教程

1、安装包 扫描下方二维码关注「软知社」,后台回复【041】三位数字即可免费获取分享链接,无广告拒绝套路; 2、安装教程双击安装,弹窗安装对话框Chinese - 点击OK按钮选择组件,默认方式,点击下一步等待进度安装,安装完成,点击完成按钮安装完成,点击关闭,不更新补丁操…

台达 hmi 人机 B10E615 备份 上传 二娃备忘 erwa.cn

台达DOP-B系列程序的上载下载操作说明 1、传输时要先进入SYS界面,在屏幕的空白处长按3秒以上,弹出如下图:确定点 系统设置-MISC 改为USBCOMMMODE:1进入 上载下载标准模式选择COM1到这个界面就可以上载下载程序了。 2、通讯电缆的制作和连接: 电缆有2种,一种是USB方口打印…

Sentinel整合Nacos实现持久化

想要实现Sentinel持久化,首先我们得思考为什么需要持久化?通俗来说就是:每次服务启动,都得重新去Sentinel dashboard中配置Sentinel的各种规则。例如流量规则、热点规则、熔断规则、授权规则。当服务数量众多时,一旦服务重新启动,所有规则都被清空,需要重新为每一个服务…

数码管驱动原厂-LED显示驱动VK1616 SOP16/DIP16抗干扰数显驱动芯片【FAE技术支持】

产品品牌:永嘉微电/VINKA 产品型号:VK1616 封装形式:SOP16/DIP16 概述 VK1616是一种数码管或点阵LED驱动控制专用芯片,内部集成有3线串行接口、数据 锁存器、LED 驱动等电路。SEG脚接LED阳极,GRID脚接LED阴极,可支持7SEGx4GRID 的点阵LED显示面板。采用SOP16/DIP16的封装…