2024/09/26 模拟赛总结

news/2024/9/27 11:51:01

rk4,\(0+30+40+30=100\),T1挂惨了

#A. 智乃的差分

分类讨论,由于 \(a_i\ge0\),当 \(x < 0\) 时,可以直接升序排列

\(x > 0\) 时,大部分情况下可以降序排列,但可能会出现 \(a_1=x\) 的情况,就可以找到第一个不为 \(x\) 且不为 \(0\) 的数,swap 掉即可

然后是最麻烦的 \(x=0\),当出现最多的数出现次数大于 \(\lceil\frac{n}{2}\rceil\),一定无解,如果等于,还要分类。如果这个最多的数不是 \(0\),就直接和其他数插空放,如果是 \(0\),当 \(n\) 是偶数时,可以将所有偶数位放 \(0\),其他位插空放,如果时奇数,则无解

否则,由于最大出现次数小于 \(\lceil\frac{n}{2}\rceil\),排序后直接按顺序先放奇数位再放偶数位即可,此时如果第一位等于 \(x\),就把数组 reverse

// BLuemoon_
#include <bits/stdc++.h>using namespace std;const int kMaxN = 1e5 + 5;int t, n, a[kMaxN], c[kMaxN], x, mx = -1, k;
map<int, int> mp;int main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);freopen("difference.in", "r", stdin), freopen("difference.out", "w", stdout);for (cin >> t; t; t--, mp.clear(), mx = -1) {cin >> n >> x;for (int i = 1; i <= n; i++) {cin >> a[i];}if (n == 1) {cout << (x == a[1] ? "no" : "yes") << '\n';(x != a[1]) && (cout << a[1] << '\n');continue;}if (x < 0) {sort(a + 1, a + n + 1);} else if (x > 0) {sort(a + 1, a + n + 1, greater<int>());bool flag = 1;if (a[1] == x) {for (int i = 2; i <= n; i++) {if (a[i] != a[1]) {(a[i] == 0) ? (flag = 1) : (swap(a[1], a[i]), flag = 0);break;}}if (flag) {cout << "no\n";continue;}}} else {int e = (n / 2) + (n % 2), v;for (int i = 1; i <= n; i++) {mp[a[i]]++, (mx < mp[a[i]]) && (mx = mp[a[i]], v = a[i]);}if (mx > e) {cout << "no\n";continue;}if (mx == e) {if (v == x) {if (n & 1) {cout << "no\n";continue;}for (int i = 2; i <= n; i += 2) {c[i] = v;}for (int i = 1, j = 1; i <= n; i += 2, j++) {for (; a[j] == v; j++) {}c[i] = a[j];}cout << "yes\n";for (int i = 1; i <= n; i++) {cout << c[i] << ' ';}cout << '\n';continue;}for (int i = 1; i <= n; i += 2) {c[i] = v;}for (int i = 2, j = 1; i <= n; i += 2, j++) {for (; a[j] == v; j++) {}c[i] = a[j];}} else {sort(a + 1, a + n + 1), k = 1;if (a[1] == x) {reverse(a + 1, a + n + 1);}for (int i = 1; i <= n; i += 2, k++) {c[i] = a[k];}for (int i = 2; i <= n; i += 2, k++) {c[i] = a[k];}}for (int i = 1; i <= n; i++) {a[i] = c[i];}}cout << "yes\n";for (int i = 1; i <= n; i++) {cout << a[i] << ' ';}cout << '\n';}return 0;
}

#B. 牛牛的旅行

比较典的拆贡献题,显然对于总长度和总最大值可以分开解决,总长度可以使用换根 dp,而最大值部分稍麻烦一些

对于每一个点,定义其“影响域”为,一个最大的包含此点的连通块,其内任意路径过此点的两点之间的 \(max_{val}\) 为这个点的权值

然后对于“影响域”内的每一个点,它到“影响域”内其他点路径经过关键点的个数乘上关键点的权值。即令关键点为 \(x\)\(y\) 为“影响域”内与 \(x\) 相连的点,那么 \(x\) 的贡献为 \(\sum (size_{x}-sz_{y})\times sz_{y}\),其中 \(size\) 为“影响域”大小,\(sz\) 为“影响域”内的子树大小

按权值升序排序后计算贡献即可

// BLuemoon_
#include <bits/stdc++.h>using namespace std;
using LL = long long;const LL kP = 1e9 + 7;
const int kMaxN = 1e6 + 5;struct P {LL id, x;bool operator<(const P& _) const {return x < _.x;}
};int n;
P a[kMaxN];
LL ans, sz[kMaxN], fa[kMaxN];
bool vis[kMaxN];
vector<int> g[kMaxN];int F(int x) {return (fa[x] == x) ? x : (fa[x] = F(fa[x]));
}
void DFS(int u, int fa) {sz[u] = 1;for (int v : g[u]) {if (v != fa) {DFS(v, u), sz[u] += sz[v], ans -= sz[v] * (n - sz[v]) % kP, (ans += kP) %= kP;}}
}int main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);freopen("tour.in", "r", stdin), freopen("tour.out", "w", stdout);cin >> n;for (int i = 1, x; i <= n; i++) {cin >> x, a[i] = (P){i, x}, fa[i] = i;}for (int i = 1, u, v; i < n; i++) {cin >> u >> v, g[u].push_back(v), g[v].push_back(u);}DFS(1, 0), sort(a + 1, a + n + 1);fill(sz + 1, sz + n + 1, 1);for (int u = 1; u <= n; u++) {for (int v : g[a[u].id]) {if (vis[v]) {(ans += (a[u].x * sz[F(a[u].id)] % kP) * sz[F(v)] % kP) %= kP;int X = F(a[u].id), Y = F(v);(X != Y) && (fa[X] = Y, sz[Y] += sz[X]);}}vis[a[u].id] = 1;}cout << (ans << 1) % kP << '\n';return 0;
}

#C. 第K排列

std 写什么【】矩阵乘法啊,还是我们 csr 有实力

\(dp_{i,j}\) 为已经填了 \(i\sim n\) 位,第 \(i\) 位填了 \(j\) 的最大值,直接枚举转移即可

然后由于 \(k\) 只有 \(1000\),我们可以 DFS 暴力枚举所有填数序列,当当前值已经大于 \(k\) 时直接剪枝掉,就可以愉快的卡过去了

// BLuemoon_
#include <bits/stdc++.h>using namespace std;
using LL = long long;const int kMaxN = 1e3  + 5;int n, x, k, a[5][5];
LL dp[kMaxN][5];
map<char, int> mp;
string s, ans, tmp = "NOIP", O = "INOP";void DFS(int t, LL e) {if (t > n) {if (e >= x) {if (!--k) {cout << ans.substr(1) << '\n', exit(0);}}return;}if (s[t] == '?') {for (int i = 3; ~i; i--) {LL f = dp[t][i];(t > 1) && (f += a[mp[ans[t - 1]]][i]);if (f + e >= x) {LL cur = e;(t > 1) && (cur += a[mp[ans[t - 1]]][i]);ans[t] = O[i], DFS(t + 1, cur);}}return;}int i = mp[s[t]];ans[t] = s[t];LL f = dp[t][i];(t > 1) && (f += a[mp[ans[t - 1]]][i]);if (f + e >= x) {LL cur = e;(t > 1) && (cur += a[mp[ans[t - 1]]][i]);ans[t] = O[i], DFS(t + 1, cur);}
}int main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0), mp['I'] = 0, mp['N'] = 1, mp['O'] = 2, mp['P'] = 3;freopen("permutation.in", "r", stdin), freopen("permutation.out", "w", stdout);cin >> n >> x >> k >> s, s = ' ' + s;for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {cin >> a[mp[tmp[i]]][mp[tmp[j]]];}}fill(dp[0], dp[kMaxN - 1], -1e18);(s[n] == '?') ? (dp[n][0] = dp[n][1] = dp[n][2] = dp[n][3] = 0) : (dp[n][mp[s[n]]] = 0);for (int i = n - 1; i; i--) {if (s[i] == '?') {for (int j = 0; j < 4; j++) {for (int k = 0; k < 4; k++) {dp[i][j] = max(dp[i][j], dp[i + 1][k] + a[j][k]);}}} else {for (int j = 0; j < 4; j++) {dp[i][mp[s[i]]] = max(dp[i][mp[s[i]]], dp[i + 1][j] + a[mp[s[i]]][j]);}}}ans.resize(n + 1), DFS(1, 0);cout << "-1\n";return 0;
}

#D. 牛牛的 border

std 写什么【】后缀数组啊,还是我们 csr 有实力

直接大力 SAM,由于两个相同的子串可以唯一确定一个子串的一个 border。所以令每种字符串长度为 \(len\),出现次数为 \(p\),那么它的贡献为 \(len \times \mathrm{C}_{p}^{2}\)

建出 \(link\) 树后进行树形 dp 算式子即可

// BLuemoon_
#include <bits/stdc++.h>using namespace std;
using LL = long long;const int kMaxN = 1e5 + 5, kMaxC = 26 + 5;LL n, ans;struct SAM {struct P {LL lnk, maxl, to[kMaxC], sz;vector<int> g;};int tot, lst;P s[kMaxN << 1];SAM() {lst = tot = 0, s[0].maxl = 0, s[0].lnk = -1;}void Insert(int ch, int c, int p = 0) {for (s[c].maxl = s[p = lst].maxl + 1, s[c].sz = 1; (p != -1) && (!s[p].to[ch]); s[p].to[ch] = c, p = s[p].lnk) {}if (p == -1) {return s[lst = c].lnk = 0, void();}int ed = s[p].to[ch];if (s[p].maxl == s[ed].maxl + 1) {return s[lst = c].lnk = ed, void();}for (s[++tot] = s[ed], s[tot].sz = 0, s[tot].maxl = s[p].maxl + 1; (~p) && (s[p].to[ch] == ed); s[p].to[ch] = tot, p = s[p].lnk) {}s[ed].lnk = s[lst = c].lnk = tot;}void Update(string str, int sz) {for (int i = 0; i < sz; i++) {Insert(str[i] - 'a' + 1, ++tot);}}void Link() {for (int i = 0; i <= tot; i++) {(~s[i].lnk) && (s[s[i].lnk].g.push_back(i), 1);}}void DFS(int u, int fa) {for (int v : s[u].g) {DFS(v, u), s[u].sz += s[v].sz;}ans += (s[u].maxl + s[fa].maxl + 1) * (s[u].maxl - s[fa].maxl) * s[u].sz * (s[u].sz - 1) / 4;}
};SAM sam;
string s;int main() {freopen("border.in", "r", stdin), freopen("border.out", "w", stdout);cin >> n >> s, sam.Update(s, n), sam.Link(), sam.DFS(0, 0);cout << ans << '\n';return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

渗透测试入门

什么是渗透测试? 定义: 渗透测试完全模拟黑客可能使用的攻击技术和漏洞发现技术,对目标系统的安全做深入的探测,发现系统最脆弱的环节,以期发现和挖掘系统中存在的漏洞,然后输出渗透测试报告,并提交给网络所有者。网络所有者根据渗透人员提供的渗透测试报告,可以清晰知…

常间的css样式问题处理

flex导致文字省略失效 单独使用文字省略,按预期工作: 给元素加上flex,文字省略失效: 解决方案:flex和文字省略不要放到一个元素上。 flex布局中,文字溢出省略不生效的问题 问题展示.container {display: flex;width: 400px;border: 1px solid #000; }.content {flex: 1; …

Spring上传文件乱码问题(问号版)

Spring上传文件乱码问题(问号版) 目录Spring上传文件乱码问题(问号版)一、问题描述:二、原因分析三、解决办法 一、问题描述: spring项目上传文件,后端接收文件并获取文件名称,名称中文变成 “?”,例如:??abc()??.xml,其中问号为中文字符 // 前端传递参数 Mult…

伯俊开发回忆录---云POS待办事项增加稽核通知功能

一、事件前景总部财务稽核通知下发流程: 1.整理EXECL通知督导, 2.督导通知对应的门店, 3.收集完反馈意见汇报给分区财务审核 4.分区财务审核之后再通知总部财务审核, 这样整个稽核流程以及周期将大大影响稽核效率,因此希望在云POS门店端直接增加待办事项减少中间沟通环节。…

我,一个小白,居然用 AI 工具修改了公司前端代码!

背景 有一天同事发现公司网站的某个页面上有三个 H1 标签,懂行的都知道,有三个 H1 标签虽然不会对网站的访问产生影响,但是对于搜索引擎来讲,就比较麻烦了,因为一般搜索引擎都是靠 H1 标签、TDK 等来对网页的内容进行抓取,然后再进行质量优劣的判断。三个 H1 标签,搜索引…

Docker打包Net8.0镜像

Docker 常用命令 Docker 是一种用于构建、打包和运行应用程序的容器化工具,以下是一些常用的 Docker 命令及其说明: 1. Docker 基础命令 docker version # 查看 Docker 的版本信息 docker info # 查看 Docker 系统信息 docker build -t <image_name> . #构建镜像 docke…

利用Python开发Exporter,集成Prometheus和Grafana对进程监控

利用Python开发Exporter,集成Prometheus和Grafana对进程监控 在现代软件开发和运维中,监控是确保系统稳定运行和快速响应问题的重要手段。Prometheus和Grafana的组合是监控领域的强大工具,它们能够收集、处理和展示各种指标数据。本文将介绍如何利用Python开发一个Exporter,…

软工结对项目

这个作业属于哪个课程 结对项目这个作业要求在哪里 结对项目这个作业的目标 合作完成一个自动生成小学四则运算题目的命令行程序结对组合成员介绍结对组合成员姓名 学号 GitHub项目地址苏清仪 3222004337 GitHub项目地址张易欣 3222004811 GitHub项目地址PSP表格PSP2.1 Persona…