NOIP 模拟赛十一

news/2025/9/21 16:19:38/文章来源:https://www.cnblogs.com/qkhm/p/19101834

A.

倒序贪心即可。

点击查看

#include <bits/stdc++.h>
#define lep(i, a, b) for (int i = a; i <= b; ++i)
#define rep(i, a, b) for (int i = a; i >= b; --i)
#define il inline
#define cmx(a, b) std::max(a, b)
#define cmn(a, b) std::min(a, b)
#define gmx(a, b) a = cmx(a, b)
#define gmn(a, b) a = cmn(a, b)template <typename T>
void _debug(const T& t) { std::cerr << t << '\n'; }
template <typename T, typename... Args>
void _debug(const T& t, const Args&...res) { std::cerr << t << ' '; _debug(res...); }
#define debug(...) _debug(#__VA_ARGS__ " =", __VA_ARGS__)const int LN = 1e6 + 7;
typedef long long ll;
typedef std::pair<ll, ll> PLL;bool FIRPOS;struct node { ll S, H, P;friend bool operator < (const node& x, const node& y) { return x.P < y.P; }
}a[LN];
int n; ll T, ans;
std::priority_queue <node> d;bool ENDPOS;int main() {std::ios::sync_with_stdio(false),std::cin.tie(nullptr), std::cout.tie(nullptr);int c1 = clock(); ll s, h, p;std::cin >> n >> T;lep(i, 1, n) {std::cin >> s >> h >> p, ans += h * p;if (!s) --i, --n;else a[i] = { s, h, p };}std::sort(a + 1, a + 1 + n, [](const node& x, const node& y) { return x.S < y.S; });ll t = 0; d.push(a[n]);rep(i, n - 1, 0) {t = a[i + 1].S - a[i].S;while (!d.empty() and t) {auto x = d.top(); d.pop();if (t >= x.H) ans -= x.H * x.P, t -= x.H;else ans -= t * x.P, x.H -= t, t = 0, d.push(x);} d.push(a[i]);}std::cout << (!ans) << ' ' << ans << '\n';
#ifdef DEBUGstd::cerr << clock() - c1 << " ms " << fabs(&ENDPOS - &FIRPOS) / 1024 / 1024 << " MB\n";
#endifreturn 0;
}

B.

打表发现 \(n\) 的转移点为 \(\frac{n}{p}\)\(p\) 为不大于 \(n\) 的最大质数。
\(g_n = p\)

\[f_i = f_{\frac{i}{g_i}} + \left\lfloor\frac{n}{\frac{i}{g_i}}\right\rfloor - g_i + 1 \]

将此过程看成树结构。
动态维护答案的增量,当前 \(n\) 的所有因子的子树(不含根)全部加一,维护子树大小即可。
树高是 \(\log\) 的,因为每次除去了一个质因子。

维护每个数的因子从 \(\frac{i}{g_i}\) 继承过来后再修改,访址更连续。

点击查看代码

#include <bits/stdc++.h>
#define lep(i, a, b) for (int i = a; i <= b; ++i)
#define rep(i, a, b) for (int i = a; i >= b; --i)
#define il inline
#define cmx(a, b) std::max(a, b)
#define cmn(a, b) std::min(a, b)
#define gmx(a, b) a = cmx(a, b)
#define gmn(a, b) a = cmn(a, b)template <typename T>
void _debug(const T& t) { std::cerr << t << '\n'; }
template <typename T, typename... Args>
void _debug(const T& t, const Args&...res) { std::cerr << t << ' '; _debug(res...); }
#define debug(...) _debug(#__VA_ARGS__ " =", __VA_ARGS__)const int LN = 2e6 + 7;
typedef long long ll;
typedef std::pair<int, int> PII;bool FIRPOS;int T, n, g[LN], sz[LN]; ll ans[LN];
std::vector <int> p[LN], prm; std::bitset <LN> vis;bool ENDPOS;ll jmp(int x, int n) {if (x != n) ++sz[x]; if (x == 1) return 1;return jmp(x / g[x], n) + n / (x / g[x]) + 1 - g[x];
}int main() {std::ios::sync_with_stdio(false),std::cin.tie(nullptr), std::cout.tie(nullptr);int c1 = clock(), x;lep(i, 2, LN - 1) {if (!vis[i]) prm.emplace_back(i);for (int j : prm) if (1ll * i * j < LN) {vis[i * j] = true;if (!(i % j)) break;} else break;}for (int j : prm) lep(i, 1, LN - 1) if (1ll * i * j < LN) g[i * j] = j; else break;p[1].emplace_back(1);lep(i, 2, LN - 1) {for (auto j : p[i / g[i]]) {p[i].emplace_back(j);if ((i / g[i]) % (g[i] * j)) p[i].emplace_back(g[i] * j);}}ans[1] = 1;lep(i, 2, LN - 1) {ans[i] = ans[i - 1];for (auto v : p[i]) ans[i] += sz[v];ans[i] += jmp(i, i);}std::cin >> T;while (T--) std::cin >> n, std::cout << ans[n] << '\n';#ifdef DEBUGstd::cerr << clock() - c1 << " ms " << fabs(&ENDPOS - &FIRPOS) / 1024 / 1024 << " MB\n";
#endifreturn 0;
}

C.

最小化 \(max + min\) 太难维护了,考虑枚举 \(max\)
将边排序后依次加入,然后对于每个与 \(1\) 连通的点,更新答案为 \(w + len\)
其中, \(w\) 是边权, \(len\) 是到 \(1\) 的最小值。
维护到根最小的最小值可以用边双树,边双内的最小边是可以随便经过的,割边也是好维护的。

我们对每条边分类讨论。

  • 在最小生成树上

    • \(1\) 不在任意一个连通块内

      合并即可,不需要额外处理。

    • 否则,暴力更新另一个连通块内的答案。我们可以通过维护每个点到 \(1\) 的最短链来做到这件事。

      复杂度是 \(O(n)\) 的。

  • 不在最小生成树上且不在一个边双内

    将这个边双暴力合并,维护最短链。

    被这个过程更新答案的点一定在最小生成树上边双的根(深度最小的点)的子树内。

提前建好最小生成树,使用线段树维护 dfn 序上的答案即可。

注意到在第二个过程中,如果我们严格更新边双所在连通块的答案是很难的,所以我们直接对整个子树全部更新。

\(1\) 最短链的维护是不会出问题的,而答案我们只需要在每个连通块第一次和根连通暴力更新答案时覆盖原来的即可。

这样只有与 \(1\) 连通之后这样的更新是有效的。

复杂度 \(O(n\log n)\)

点击查看

#include <bits/stdc++.h>
#define lep(i, a, b) for (int i = a; i <= b; ++i)
#define rep(i, a, b) for (int i = a; i >= b; --i)
#define il inline
#define cmx(a, b) ((a) > (b) ? (a) : (b))
#define cmn(a, b) ((a) < (b) ? (a) : (b))
#define gmx(a, b) a = cmx(a, b)
#define gmn(a, b) a = cmn(a, b)template <typename T>
void _debug(const T& t) { std::cerr << t << '\n'; }
template <typename T, typename... Args>
void _debug(const T& t, const Args&...res) { std::cerr << t << ' '; _debug(res...); }
#define debug(...) _debug(#__VA_ARGS__ " =", __VA_ARGS__)const int LN = 2e6 + 7;
const int inf = 2e9;
typedef long long ll;
typedef std::pair<int, int> PII;bool FIRPOS;int n;
struct seg {int mn[LN << 2], tag[LN << 2];
#define ls p << 1
#define rs p << 1 | 1
#define md ((s + t) >> 1)void bd(int s = 1, int t = n, int p = 1) {mn[p] = tag[p] = inf; if (s == t) return;bd(s, md, ls), bd(md + 1, t, rs);}il void pu(int p) { mn[p] = cmn(mn[ls], mn[rs]); }il void upd(int p, int k) { gmn(mn[p], k), gmn(tag[p], k); }il void pd(int p) { if (tag[p] != inf) upd(ls, tag[p]), upd(rs, tag[p]), tag[p] = inf; }void col(int d, int v, int s = 1, int t = n, int p = 1) {if (s == t) return mn[p] = v, void(); pd(p);d <= md ? col(d, v, s, md, ls) : col(d, v, md + 1, t, rs); pu(p);}void mdy(int l, int r, int v, int s = 1, int t = n, int p = 1) {if (r < s or t < l) return; if (l <= s and t <= r) return upd(p, v); pd(p);mdy(l, r, v, s, md, ls), mdy(l, r, v, md + 1, t, rs); pu(p);}int qry(int d, int s = 1, int t = n, int p = 1) {if (s == t) return mn[p]; pd(p);return d <= md ? qry(d, s, md, ls) : qry(d, md + 1, t, rs);}
#undef ls
#undef rs
#undef md
}loc, ans; int dfn[LN], idx, sz[LN], pr[LN], dep[LN];
struct edge { int u, v, w; }E[LN]; int m;
std::vector <int> e[LN], g[LN]; std::bitset <LN> tr;
int up[LN];
struct Dsu{int fa[LN]; std::vector <int> scc[LN];int fnd(int x) { return fa[x] == x ? x : fa[x] = fnd(fa[x]); }bool mrg(int u, int v) {if ((u = fnd(u)) == (v = fnd(v))) return false;if (scc[u].size() < scc[v].size()) std::swap(u, v);for (int t : scc[v]) scc[u].emplace_back(t); scc[v].clear();if (dep[u] > dep[v]) std::swap(scc[u], scc[v]), fa[u] = v;else fa[v] = u;return true;}
}grp, scc;bool ENDPOS;il void add(int u, int v, int w) { e[u].emplace_back(v), g[u].emplace_back(w); }
il void Add(int u, int v, int w) { add(u, v, w), add(v, u, w); }
void init(int u, int fa) {dfn[u] = ++idx, dep[u] = dep[pr[u] = fa] + 1, sz[u] = 1; int v;lep(k, 0, (int)e[u].size() - 1) { v = e[u][k];if (v != fa) init(v, u), sz[u] += sz[v], up[v] = g[u][k];}e[u].clear(), g[u].clear(), grp.scc[u].emplace_back(grp.fa[u] = scc.fa[u] = u);
}int main() {std::ios::sync_with_stdio(false),std::cin.tie(nullptr), std::cout.tie(nullptr);int c1 = clock();int u, v, w;std::cin >> n >> m;lep(i, 1, n) grp.fa[i] = i, up[i] = inf;lep(i, 1, m) std::cin >> u >> v >> w, E[i] = { u, v, w };std::sort(E + 1, E + 1 + m, [](const edge& x, const edge& y) { return x.w < y.w; });lep(i, 1, m) if (grp.mrg(E[i].u, E[i].v)) tr.set(i), Add(E[i].u, E[i].v, E[i].w);init(1, 0);lep(i, 2, n) debug(pr[i], i);loc.bd(), ans.bd();lep(i, 1, m) {u = E[i].u, v = E[i].v, w = E[i].w;if (scc.fnd(u) == scc.fnd(v)) continue;if (dep[u] > dep[v]) std::swap(u, v);if (tr[i]) {loc.mdy(dfn[v], dfn[v] + sz[v] - 1, cmn(w, loc.qry(dfn[u])));if (grp.fnd(u) == grp.fnd(1))for (auto p : grp.scc[v]) ans.col(dfn[p], loc.qry(dfn[p]) + w);grp.mrg(u, v);continue;}int d = inf; u = scc.fnd(u), v = scc.fnd(v);while (u != v) {if (dep[u] < dep[v]) std::swap(u, v);gmn(d, up[u]), scc.mrg(u, pr[u]), u = scc.fnd(pr[u]);} gmn(up[u], d);if (up[u] != inf) loc.mdy(dfn[u], dfn[u] + sz[u] - 1, up[u]),ans.mdy(dfn[u], dfn[u] + sz[u] - 1, up[u] + w);}lep(i, 2, n) std::cout << ans.qry(dfn[i]) << '\n';#ifdef DEBUGstd::cerr << clock() - c1 << " ms " << fabs(&ENDPOS - &FIRPOS) / 1024 / 1024 << " MB\n";
#endifreturn 0;
}

D.

我们将问题放到值域上来考虑。

每处的高地有两种选择,接到前面的枢纽上,或者花费代价延迟决策。

所以我们就记录下 \(f[i, j, k]\) 表示考虑了 \([1, i]\) 的值域,目前有 \(j\) 个枢纽,\(k\) 个高地延迟决策。

注意到如果我们将一个高地留在这个地方,后面可供选择的枢纽数是不变的,因为其自带一个枢纽。

所以我们肯定会将能够放下的所有高地全部留下。

也就是说,记 \(cnt_i\) 为等级为 \(i\) 的高地数目,则 \(f[i, j, k]\) 能够转移到 \(f[i + 1, j, k + cnt[i] - j]\)

然后再完全背包考虑一下当前新买一些枢纽给后面用,费用就是前缀最小值。

因为多个最小值时根是不固定的,所以我们新建一个拥有一个枢纽的虚点做根就可以了。

但是值域太大了,我们很自然地想离散化。

考虑当相邻两个 \(cnt\) 之间有空余会发生什么,肯定是每抬升一步,就会留下 \(j\) 个高地,因为这样的决策是一定不劣的。

我们可以通过等差数列求和轻松算出可以转移到哪个状态。

同时注意,在 \(i\) 处买的枢纽在 \(i+1\) 便可以用了,所以我们将所有的 \(a_i+1\) 也纳入决策点就行了。

复杂度 \(O(n^3)\)

点击查看

#include <bits/stdc++.h>
#define lep(i, a, b) for (int i = a; i <= b; ++i)
#define rep(i, a, b) for (int i = a; i >= b; --i)
#define il inline
#define cmx(a, b) std::max(a, b)
#define cmn(a, b) std::min(a, b)
#define gmx(a, b) a = cmx(a, b)
#define gmn(a, b) a = cmn(a, b)
#define int __int128template <typename T>
void _debug(const T& t) { std::cerr << t << '\n'; }
template <typename T, typename... Args>
void _debug(const T& t, const Args&...res) { std::cerr << t << ' '; _debug(res...); }
#define debug(...) _debug(#__VA_ARGS__ " =", __VA_ARGS__)const int LN = 1000 + 7;
typedef long long ll;
typedef std::pair<int, int> PII;bool FIRPOS;const ll inf = 1e12;
int n, a[LN], b[LN], B[LN], cnt[LN]; int P, f[2][LN][LN];
std::vector <int> Ab; int V;bool ENDPOS;int read() {int x = 0; char c = getchar();while (c < '0' or c > '9') c = getchar();while (c>= '0' and c<='9') x = (x << 3) + (x << 1) + c - '0', c = getchar();return x;
}signed main() {std::ios::sync_with_stdio(false),std::cin.tie(nullptr), std::cout.tie(nullptr);int c1 = clock();n = read(), P = read(); Ab.emplace_back(-1), Ab.emplace_back(0);lep(i, 1, n) a[i] = read(), b[i] = read(), Ab.emplace_back(a[i]), Ab.emplace_back(a[i] + 1);std::sort(Ab.begin(), Ab.end()), Ab.erase(std::unique(Ab.begin(), Ab.end()), Ab.end());V = Ab.size(), Ab.emplace_back((int)2e9);std::memset(B, 0x3f, sizeof(B));lep(i, 1, n) {a[i] = std::lower_bound(Ab.begin(), Ab.end(), a[i]) - Ab.begin();++cnt[a[i]], gmn(B[a[i]], b[i]);}int p = 0, nk, dl; std::memset(f, 0x3f, sizeof(f));f[p][1][0] = 0;lep(i, 0, V - 1) {std::memset(f[p ^ 1], 0x3f, sizeof(f[p ^ 1]));lep(j, 1, n) lep(k, 0, n) if (f[p][j][k] < inf) {nk = cmx((int)0, k + cnt[i] - j);dl = (nk + j - 1) / j;if (Ab[i] + dl < Ab[i + 1]) gmn(f[p ^ 1][j][0], f[p][j][k] + (j * (dl + 1) * dl / 2 - (dl * j - nk) * dl) * P);else dl = Ab[i + 1] - Ab[i] - 1, nk -= dl * j, gmn(f[p ^ 1][j][nk], f[p][j][k] + (j * dl * (dl + 1) / 2 + nk * (dl + 1)) * P);} p ^= 1;lep(k, 0, n) lep(j, 1, n) gmn(f[p][j][k], f[p][j - 1][k] + B[i]);}int ans = inf;lep(i, 0, n) gmn(ans, f[p][i][0]);std::cout << (ll)ans << '\n';return 0;
}

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

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

相关文章

Proxy 库解析(四)

test一切伟大的行动和思想,都有一个微不足道的开始。 There is a negligible beginning in all great action and thought.

warm-flow 监听器对象获取问题

初次使用warm-flow 实现了 Listener 接口,配置名字和路径也有写对,但监听器一直没启动,查看底层代码Listener listener = (Listener) FrameInvoker.getBean(clazz);在要执行监听器时,一直获取不到对象,很疑惑,打…

Hexo Butterfly 5.4 分页问题 YAML 错误 解决方法总结

Hexo Butterfly 5.4 分页问题 & YAML 错误 解决方法总结 本次问题核心是 “首页分页显示不全(仅 1、2…11)” 与 “hexo clean 报错 YAML 重复键”,最终通过配置文件修正 + 主题模板调整解决,具体步骤如下: 一…

FPGA硬件设计6 ZYNQ外围-HDMI、PCIE、SFP、SATA、FMC - 教程

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

js逆向:某Q音乐平台请求数据模拟生成

@目录1. 加密原理2. 参考代码内容仅供学习使用,不能用于商业活动,且不能在该网站高用户访问时频繁访问,以免对对应服务器造成影响。1. 加密原理 该音乐平台加密数据为如下图片这个:所加密的数据data和这篇文章里的…

第十一届中国大学生程序设计竞赛网络预选赛(CCPC Online 2025)

Preface最近因为队友要准备预推免,很久没有一起训练过了;我个人也是把大部分精力都放在科研方面,算是挺久没写代码了 同时因为这场撞了本校预推免的原因,导致学校很多队伍被迫重组,但好在我们队没受影响堪堪凑齐了…

完整教程:数据结构 栈和队列、树

完整教程:数据结构 栈和队列、树pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco&q…

深入解析:【ubuntu】ubuntu中找不到串口设备问题排查

深入解析:【ubuntu】ubuntu中找不到串口设备问题排查pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&qu…

酵母双杂交技术:高通量筛选的突破与不可忽视的三大局限性

在后基因组时代,解析蛋白质相互作用网络已成为理解生命活动机制、挖掘疾病靶点的核心任务。酵母双杂交技术通过不断革新,已从 “一对一” 的简单互作验证,升级为 “组学水平” 的高通量筛选工具 —— 不仅能覆盖全基…

ubuntu20.04测试cuda

import torch# 1. 检查 PyTorch 版本 print("PyTorch 版本:", torch.__version__) # 应为 2.4.0# 2. 检查 CUDA 是否可用 print("CUDA 可用:", torch.cuda.is_available()) # 应为 True# 3. 检查…

Python lambda

Python lambda 漫思

Android Studio 配置国内源

腾讯:https://mirrors.cloud.tencent.com/AndroidSDK/ 阿里:https://mirrors.aliyun.com/android.googlesource.com/

PyCharm项目上传GitHub仓库(笔记) - 教程

PyCharm项目上传GitHub仓库(笔记) - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "…

从RAG出发

从RAG出发 1. RAG的概念和背景 1.1 什么是RAG RAG(Retrieval-Augmented Generation,检索增强生成)是一种将 信息检索 与 大语言模型生成 融合的技术架构。 其核心思想是:在模型生成前,通过检索外部知识库获取相关…

软件工程第二次作业——第一次个人编程作业

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

【树状数组】codeforce 1288 E. Messenger Simulator

View Post【树状数组】codeforce 1288 E. Messenger Simulator题目 https://codeforces.com/problemset/problem/1288/E 题解 用以下测试用例进行讲解: 4 2 3 2上述测试用例的执行过程如图所示:初始状态下,第 \(i\)…

exsi 6.7 打补丁

exsi 6.7 打补丁exsi 6.7 打补丁esxi 6.7 打补丁WARNING:All commands run on the ESXi shell are logged and may be included insupport bundles. Do not provide passwords directly on the command line.Most tool…

Ubuntu 24.04 安装 DaVinci Resolve

Ubuntu 24.04 安装 DaVinci Resolve Step1: 下载并安装 chmod +x DaVinci_Resolve_Studio_19.0_Linux.run sudo ./DaVinci_Resolve_Studio_19.0_Linux.run -i可能会遇到依赖的问题, 需要先安装以下的几个库, 再以跳过检…

Promise中处理请求超时问题

1. 使用 Promise.race() 处理超时Promise<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="https://code.jquery.com/jquery-3.6.0.min.js">&l…

图解26:老生常谈的OSI网络模型

哈哈,之前画的不能在老的图了,重新拿出来让AI加个码看看效果,没有一点失真还不错,