2025 CCPC 网络赛

news/2025/9/21 18:16:07/文章来源:https://www.cnblogs.com/Kescholar/p/19103933

C. 造桥与砍树

魔改 prim。

回顾经典的prim算法,从第一个点开始,每次找权值最小的边加入,然后更新到每个点的距离和边的起点,以此往复。

对于这道题来讲,每次更新到其他 \(n-1\) 个点的最小权值显然复杂度太大,但按照贪心的来讲,我们其实每次只选最小的那条边加入而已,所以对于点 \(u\) 来说每次二分去找到权值最接近 \(k-t_u\) 的点即可,如果没有,那就选点权最小的加进去。

按照 prim 算法,维护一条边的两个点,如果我们准备要加入的这个点和我们之前已经连边的点是一个集合,那就不用再加这个点了,重新选一条边加入堆维护即可;否则加入这个点,再对两个点都选取一条边加入堆维护。

点击查看代码
#include <bits/stdc++.h>using namespace std;using i64 = long long;void solve() {int n, k;cin >> n >> k;set<array<int,2>> s;vector<int> a(n + 1);for (int i = 1; i <= n; i += 1) {cin >> a[i];a[i] %= k;s.insert({a[i], i});}auto get = [&](int x)->array<int,2> {auto t = s.lower_bound({k - x, 0});return t == s.end() ? *s.begin() : *t;};priority_queue<array<int,3>,vector<array<int,3>>,greater<>> Q;auto [w1, st] = *s.begin();s.erase(s.begin());auto [w2, nxt] = get(w1);i64 ans = 0;Q.push({(w1 + w2) % k, st, nxt});while (Q.size()) {auto [d, u, v] = Q.top();Q.pop();if (!s.count({a[v], v})) {auto [w, x] = get(a[u]);Q.push({(w + a[u]) % k, u, x});continue;}ans += d;s.erase(s.lower_bound({a[v], v}));if (s.empty()) {break;}auto [w1, x] = get(a[v]);Q.push({(w1 + a[v]) % k, v, x});auto [w2, y] = get(a[u]);Q.push({(w2 + a[u]) % k, u, y});}cout << ans << "\n";}
int main() {ios::sync_with_stdio(false);cin.tie(nullptr);int t;cin >> t;while (t--) {solve();}return 0;
}

换了 Boruvka 算法,听说有人过了,但是我的被卡了(悲qwq

T 掉的代码:

点击查看代码
#include <bits/stdc++.h>using namespace std;using i64 = long long;struct DSU {std::vector<int> f, siz;DSU() {}DSU(int n) {init(n);}void init(int n) {f.resize(n);std::iota(f.begin(), f.end(), 0);siz.assign(n, 1);}int find(int x) {while (x != f[x]) {x = f[x] = f[f[x]];}return x;}bool same(int x, int y) {return find(x) == find(y);}bool merge(int x, int y) {x = find(x);y = find(y);if (x == y) {return false;}siz[x] += siz[y];f[y] = x;return true;}int size(int x) {return siz[find(x)];}
};void solve() {int n, k;cin >> n >> k;multiset<array<int,2>> s;vector<int> a(n + 1);vector<vector<int>> num(n + 1);for (int i = 1; i <= n; i += 1) {cin >> a[i];a[i] %= k;s.insert({a[i], i});num[i].push_back(i);}auto get = [&](int x)->array<int,2> {auto t = s.lower_bound({k - x, 0});return t == s.end() ? *s.begin() : *t;};i64 ans = 0;DSU dsu(n + 1);while (true) {for (int i = 1; i <= n; i += 1) {if (dsu.find(i) != i) {continue;}for (auto x : num[i]) {s.extract({a[x], x});}int Min = INT_MAX, nxt = -1;for (auto x : num[i]) {auto [w, y] = get(a[x]);w = (w + a[x]) % k;if (Min > w) {Min = w, nxt = y;if (Min == 0) {break;}}}for (auto x : num[i]) {s.insert({a[x], x});}if (nxt != -1) {auto &ve = num[dsu.find(nxt)];num[i].insert(num[i].end(), ve.begin(), ve.end());dsu.merge(i, nxt);ans += Min;}}if (dsu.size(1) == n) {break;}}cout << ans << "\n";}
int main() {ios::sync_with_stdio(false);cin.tie(nullptr);int t;cin >> t;while (t--) {solve();}return 0;
}

G. 序列与整数对

根号分治。

对出现次数小于 \(B\) 的暴力枚举,然后二分另一个数的贡献统计即可,取 \(B = \sqrt{\frac{n^2}q}\) 时,复杂度为 \(O(q\sqrt{n}\log n)\)

直接暴力枚举也行,按哪个出现次数少就枚举哪个,然后记忆化,这样下来的复杂度貌似均摊也和上面一样。

点击查看代码
#include <bits/stdc++.h>using namespace std;using i64 = long long;int main() {ios::sync_with_stdio(false);cin.tie(nullptr);int n, q;cin >> n >> q;vector<int> a(n + 1);map<int, vector<int>> mp;for (int i = 1; i <= n; i += 1) {cin >> a[i];mp[a[i]].push_back(i);}int B = sqrt(n / q * n);map<array<int,2>,i64> ans;while (q --) {int x, y;cin >> x >> y;if (ans.count({x, y})) {cout << ans[ {x, y}] << "\n";continue;}i64 res = 0;int m = mp[x].size(), k = mp[y].size();if (x == y) {cout << 1LL * (m - 1) * m / 2 << "\n";continue;}else if (m < B || m >= B && k >= B && m < k) {for (auto &u : mp[x]) {res += mp[y].end() - lower_bound(mp[y].begin(), mp[y].end(), u);}}else {for (auto &v : mp[y]) {res += lower_bound(mp[x].begin(), mp[x].end(), v) - mp[x].begin();}}ans[ {x, y}] = res;cout << res << "\n";}return 0;
}

离线离散化,预处理大于 \(\sqrt n\) 的部分,对于两个都小于 \(\sqrt n\) 的部分,可以直接双指针处理,这部分最多也是 \(\sqrt n\) 次,所以复杂度为 \(O(n \sqrt n + q(\log n +\sqrt n))\)

点击查看代码
#include<bits/stdc++.h>
using namespace  std;
#define endl '\n'
const int N=1e5+3;
#define int long long
int n,q;
void solve() {cin >> n >> q;int K = sqrt(n);vector<int> a(n + 1);vector<int> p;for (int i = 1; i <= n; ++i) {cin >> a[i];p.push_back(a[i]);}vector<array<int, 2>> Q;for (int i = 0; i < q; ++i) {int x, y;cin >> x >> y;Q.push_back({x, y});p.push_back(x);p.push_back(y);}std::sort(p.begin(), p.end());p.erase(unique(p.begin(), p.end()), p.end());int m=p.size();vector<int> cnt(m + 3);vector<int> mp[m +3];for (int i = 1; i <= n; ++i) {a[i] = lower_bound(p.begin(), p.end(), a[i]) - p.begin() + 1;mp[a[i]].push_back(i);cnt[a[i]]++;}vector<int> g1[m+3];vector<int> g2[m+3];for (int i = 0; i < q; ++i) {Q[i][0] = lower_bound(p.begin(), p.end(), Q[i][0]) - p.begin() + 1;Q[i][1] = lower_bound(p.begin(), p.end(), Q[i][1]) - p.begin() + 1;int x = Q[i][0];int y = Q[i][1];g1[x].push_back(y);g2[y].push_back(x);}vector<int> ans1[m+3];vector<int> ans2[m+3];for (int i = 1; i <= m; ++i) {std::sort(g1[i].begin(), g1[i].end());g1[i].erase(unique(g1[i].begin(), g1[i].end()), g1[i].end());ans1[i].resize(g1[i].size());std::sort(g2[i].begin(), g2[i].end());g2[i].erase(unique(g2[i].begin(), g2[i].end()), g2[i].end());ans2[i].resize(g2[i].size());}vector<int> idx(m + 3, -1);for (int i = 1; i <= m; ++i) {if (g1[i].empty())continue;if (cnt[i] >= K) {int p = 0;for (auto x: g1[i]) {idx[x] = p++;}int sum = 0;for (int j = 1; j <= n; ++j) {int y = a[j];if (idx[y] != -1) {if (cnt[y] < K) {ans1[i][idx[y]] += sum;}}if (y == i)sum++;}for (auto x: g1[i]) {idx[x] = -1;}}}for (int i = 1; i <= m; ++i) {if (g2[i].empty())continue;if (cnt[i] >= K) {int p = 0;for (auto x: g2[i]) {idx[x] = p++;}int sum = 0;for (int j = n; j >= 1; --j) {int y = a[j];if (idx[y] != -1) {ans2[i][idx[y]] += sum;}if (y == i)sum++;}for (auto x: g2[i]) {idx[x] = -1;}}}for (auto [x, y]: Q) {if (cnt[x] >= K and cnt[y] < K) {int id= lower_bound(g1[x].begin(), g1[x].end(),y)-g1[x].begin();cout<<ans1[x][id]<<endl;} else if (cnt[y] >= K) {int id= lower_bound(g2[y].begin(), g2[y].end(),x)-g2[y].begin();cout<<ans2[y][id]<<endl;} else {
//            cout<<x<<' '<<y<<endl;int sum = 0;int l = 0;for (int i = 0; i < mp[y].size(); ++i) {auto id = mp[y][i];while (l < mp[x].size() and mp[x][l] < id) {l++;}sum += l;
//                cout<<sum<<' ';}
//            cout<<endl;cout<<sum<<endl;}}
}signed main(){ios::sync_with_stdio(false),cin.tie(0);int t=1;
//    cin>>t;while (t--){solve();}
}

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

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

相关文章

安装windows11跳过账户登录

这个最快!!能跳过obbe start ms-cxh:localonlyWindows 11 跳过强制登录微软账户的方法方法1:使用错误的邮箱和密码。比如使用1@1.com,密码随便输入。 方法2:用快捷键“shift+F10”调出CMD命令窗口,输入“star…

TCM安全学院夏季大促与免费网络安全课程发布

TCM安全学院发布安德鲁贝利尼的紧急消息,宣布夏季大促活动,提供网络安全认证和培训折扣,以及新发布的免费网络安全入门课程,适合初学者学习渗透测试和黑客技术。最后听到安德鲁的消息!:face_screaming_in_fear: 点…

博客园插入bilibili视频

默认的<!--第三方:会自动播放--> <iframe src="https://xbeibeix.com/api/bilibili/biliplayer/?url=https://www.bilibili.com/video/BV1Fz4y1f7Wc" scrolling="no" border="0&q…

软件工程第一次编程作业

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/Class34Grade23ComputerScience这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/Class34Grade23ComputerScience/homework/13477这个作业的目标 实…

WO Mic - 免费麦克风

WO Mic可以将您的手机变成电脑麦克风。您无需支付一分钱购买任何设备。如果您选择无线传输,它也是便携的。数百万用户已经安装并每天都在使用它进行通话、录音、语音遥控等活动。 三大组件协同工作以实现这一点:WO M…

AudioRelay —— 让电脑使用手机的麦克风和扬声器

写在前面 总所周知,电脑的麦克风和扬声器一直是很垃圾的水平,和手机相比差了很多,那能不能使用手机的硬件设备来给电脑使用呢,也能省个音箱的钱呢?答案是可以的。那就是使用AudioRelay。前段时间介绍了WO Mic,他…

【小白学算法】矩阵快速幂超详细解析+例题[HDU - 2802]

用于高效解决线性递推问题 前言 在算法竞赛和实际编程中,我们经常遇到需要计算矩阵的高次幂的问题。如果直接用朴素的矩阵乘法来计算,时间复杂度会达到O(n k),其中n是矩阵的维度,k是幂次。当k非常大时(比如\(10^…

lyms 的神秘歌单

关于这个闲话。还有 50 min 就要回 whk 了,我们可以干点什么呢?wy_x and lyms : 写闲话!所以就写。 说实在的根本不知道能写什么。 要不然给自己喜欢的曲子列个列表。 就当是什么神秘歌单了。 update on 9.21 推什么…

大学园区二手书交易强大的平台(代码+数据库+LW)

大学园区二手书交易强大的平台(代码+数据库+LW)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas",…

深入解析:SpringMVC的请求接收与结果响应

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Element UI框架中自定义input组件的placeholder样式

Element UI是基于Vue.js的组件库,提供了一系列的组件,方便在Vue应用程序中快速使用。对于自定义input组件的placeholder样式,可以通过CSS覆盖默认样式来实现。以下是对Element UI中input组件的placeholder样式自定义…

go语言数组的方法

go语言数组的方法 漫思

【C++】类与结构体的区别

区别 技术上 实际上类与结构体在技术层面除了可见性并没有区别,唯一值得一提的区别就是: class类默认情况下其中的变量、函数都为private私有的。 struct结构体默认情况下则都是public公共的。 用法上 何时使用class…

Linux云端服务器上部署Spring Boot应用

在Linux云服务器上部署Spring Boot应用环境准备:确保Java JDK已安装。Spring Boot通常需要Java 8或更高版本。使用 java -version来确认Java版本。 安装Maven(如果是Maven项目)或Gradle(如果是Gradle项目),这取决…

HTML表单验证:确认input元素输入为具有特定整数和小数位数的数值

为了确保HTML表单中的 input元素接收具有特定整数位和小数位数的数值,您需要利用HTML和JavaScript进行前端验证。在HTML5中,可以使用内建的表单验证功能,比如 pattern属性,然而 pattern属性主要用于字符串的正则表…

课前问题思考3

1.什么样的方法应该用static修饰?不用static修饰的方法往往具有什么特性?Student的getName应该用static修饰吗?什么样的方法应该用static修饰?方法不依赖于类的实例状态。 方法提供的功能与类的实例无关。 工具类方…

实用指南:Docker部署Drawnix开源白板工具

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

go静态方法

go静态方法 漫思

在CentOS上配置SVN至Web目录的自动同步

配置SVN(Subversion)到Web目录的自动同步在CentOS系统中是一种有效的代码部署方法,它可以让团队成员更便捷地管理和发布Web项目。以下是如何在CentOS上实现SVN仓库到Web目录的自动同步的详细步骤。= 1. 安装并配置S…

AIGC在游戏开发中的革命性影响:从生产效率到体验创新 - 详解

AIGC在游戏开发中的革命性影响:从生产效率到体验创新 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Cons…