『模拟赛』NOIP2024加赛5

Rank

反向挂分大王

image

A. 暴力操作(opt)

签,但是没有人签。

都想到了二分和更新 c 值,但是 c 多多少少没更到最优。

首先还是调和级数预处理,倒序取 min。然后考虑到超过 \(m\) 的也有可能产生更小的代价,因此 \(\mathcal{O(n)}\) 枚举一遍找到最小的 \(j\) 使 \(i\times j\gt m\),全部赋到 \(c_{m+1}\) 上,然后再倒序取一遍 min 就能更好的更新。

check 有 \(\mathcal{O(n)}\) 的双指针写法,我直接没改赛时的 \(\mathcal{O(n\log n)}\) 的二分,所以复杂度是 \(\mathcal{O(n\ln n+n\log^2n)}\) 的。

点击查看代码
#include<bits/stdc++.h>
#define fo(x, y, z) for(int (x) = (y); (x) <= (z); (x)++)
#define fu(x, y, z) for(int (x) = (y); (x) >= (z); (x)--)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define lx ll
inline lx qr()
{char ch = getchar(); lx x = 0, f = 1;for(; ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;for(; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 3) + (x << 1) + (ch ^ 48);return x * f;
}
#undef lx
#define qr qr()
#define pii pair<int, int>
#define ppp pair<pii, pii>
#define fi first
#define se second
#define M_P(x, y) make_pair(x, y)
#define P_B(x) push_back(x)
const int Ratio = 0;
const int N = 5e5 + 5;
const int mod = 1e9 + 7;
ll n, m, k;
ll a[N], c[N];
namespace Wisadel
{bool Wck(int x){ll ned = 0;fo(i, 1, n / 2 + 1) if(a[i] > x){int l = 2, r = a[i] + 1;while(l < r){int mid = (l + r) >> 1;if(a[i] / mid <= x) r = mid;else l = mid + 1;}ned += c[r];if(ned > k) return 0;}return 1;}short main(){freopen("opt.in", "r", stdin), freopen("opt.out", "w", stdout);n = qr, m = qr, k = qr;fo(i, 1, n) a[i] = qr;fo(i, 1, m) c[i] = qr;fo(i, 2, m) fo(j, 1, min(m / i, 1ll * i))c[i * j] = min(c[i * j], c[i] + c[j]);fu(i, m - 1, 1) c[i] = min(c[i], c[i + 1]);c[m + 1] = 1e9;fo(i, 2, m){int zc = m / i + 1;c[m + 1] = min(c[m + 1], c[i] + c[zc]);}fu(i, m, 1) c[i] = min(c[i], c[i + 1]);sort(a + 1, a + 1 + n);int l = 0, r = a[n / 2 + 1];while(l < r){int mid = (l + r) >> 1;if(Wck(mid)) r = mid;else l = mid + 1;}printf("%d\n", r);return Ratio;}
}
signed main(){return Wisadel::main();}
// Now there's only one thing I can do
// Fight until the end like I promised to

B. 异或连通(xor)

比较套路。

主要需要想到对询问建 trie 而不是边,那么容易发现一条边只会在 \(\log V\) 个子树中出现。按线段树分治的思想,直接在 trie 树上分治,找到对于每一个询问合法的线段存到点上,然后对 trie 树做一遍 dfs,过程中做启发式合并,回溯时撤销即可。

注意并查集不要路径压缩!复杂度 \(\mathcal{O(n\log n\log V)}\)

点击查看代码
#include<bits/stdc++.h>
#define fo(x, y, z) for(int (x) = (y); (x) <= (z); (x)++)
#define fu(x, y, z) for(int (x) = (y); (x) >= (z); (x)--)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define lx ll
inline lx qr()
{char ch = getchar(); lx x = 0, f = 1;for(; ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;for(; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 3) + (x << 1) + (ch ^ 48);return x * f;
}
#undef lx
#define qr qr()
#define pii pair<int, int>
#define fi first
#define se second
#define M_P(x, y) make_pair(x, y)
#define P_B(x) push_back(x)
const int Ratio = 0;
const int N = 1e5 + 5;
const int mod = 1e9 + 7;
int n, m, k, q;
struct rmm{int u, v, w;} e[N];
int que[N], pre[N];
namespace Wisadel
{ll fx[N], siz[N];int Wfind(int x){if(x == fx[x]) return x;return Wfind(fx[x]);}void Wmerge(int u, int v){u = Wfind(u), v = Wfind(v);if(u == v) return ;if(siz[u] < siz[v])fx[u] = v, siz[v] += siz[u];else fx[v] = u, siz[u] += siz[v];}int t[N * 20][2], tot;vector<pii> d[N * 20];vector<int> v[N * 20];ll ans[N * 20];void Wins(int x, int id){int now = 0;fu(i, 30, 0){int to = (x >> i) & 1;if(!t[now][to]) t[now][to] = ++tot;now = t[now][to];}pre[id] = now;}void Wupd(int x, int id){int now = 0;fu(i, 30, 0){int to = (x >> i) & 1, pd = (k >> i) & 1;if(pd){if(t[now][to]) v[t[now][to]].P_B(id);now = t[now][to ^ 1];}else now = t[now][to];if(!now) return ;}}void Wdfs(int now, ll sum){ans[now] = sum;for(int i : v[now]){int _ = Wfind(e[i].u), __ = Wfind(e[i].v);if(_ == __) continue;if(siz[_] < siz[__]) swap(_, __);ans[now] += siz[_] * siz[__];fx[__] = _, siz[_] += siz[__];d[now].P_B(M_P(_, __));}if(t[now][0]) Wdfs(t[now][0], ans[now]);if(t[now][1]) Wdfs(t[now][1], ans[now]);fu(i, d[now].size() - 1, 0){pii zc = d[now][i];fx[zc.se] = zc.se;siz[zc.fi] -= siz[zc.se];}}short main(){freopen("xor.in", "r", stdin), freopen("xor.out", "w", stdout);n = qr, m = qr, q = qr, k = qr;fo(i, 1, n) fx[i] = i, siz[i] = 1;fo(i, 1, m) e[i].u = qr, e[i].v = qr, e[i].w = qr;fo(i, 1, q) que[i] = qr, Wins(que[i], i);fo(i, 1, m) Wupd(e[i].w, i);Wdfs(0, 0);fo(i, 1, q) printf("%lld\n", ans[pre[i]]);return Ratio;}
}
signed main(){return Wisadel::main();}
// Now there's only one thing I can do
// Fight until the end like I promised to

C. 诡异键盘(keyboard)

huge:你们上届学长只有三个改出来了

放最后改了,懂了大概思路。

赛时纯唐纯暴力做法打的 20pts 拿到了 70pts。

先做删串需要的同余最短路,然后建 trie 做 dp,具体不太会。

D. 民主投票(election)

好像是真正的签,不过为什么我需要卡常才能过?

首先需要求得树上最多票数最少 \(k\) 是多少,这个容易想到二分去做,设 \(f_i\) 为子树 \(i\) 在某个票数限制下需要向上贡献的票数,判断可行与否只需根据 \(f1=0\)。然后对于子树大小减一大于 \(k\) 点一定可行,小于 \(k\) 的一定不行,这两点都很显然。

关键在处理子树大小减一等于 \(k\) 的点。办法是以 \(k-1\) 为限制再 dp 一次。此时只有当前点的限制为 \(k\),则若 \(f_x=1\),那么解除限制后才满足 \(f_x=0\)。只有 \(x\) 到根路径上的点的 \(f\) 都为 0 且 \(f_1=1\) 时才合法,因为只有此时 \(f_x\) 限制加一才能解除 \(f_1\) 的限制。

时间复杂度 \(\mathcal{O(n\log n)}\),不知道为啥要卡常。

点击查看代码
// ubsan: undefined
// accoders
#include<bits/stdc++.h>
#define fo(x, y, z) for(int (x) = (y); (x) <= (z); (x)++)
#define fu(x, y, z) for(int (x) = (y); (x) >= (z); (x)--)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define lx ll
inline lx qr()
{char ch = getchar(); lx x = 0, f = 1;for(; ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;for(; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 3) + (x << 1) + (ch ^ 48);return x * f;
}
#undef lx
#define qr qr()
#define pii pair<int, int>
#define ppp pair<pii, pii>
#define fi first
#define se second
#define M_P(x, y) make_pair(x, y)
#define P_B(x) push_back(x)
const int Ratio = 0;
const int N = 2e6 + 5;
const int mod = 1e9 + 7;
int n;
int hh[N], to[N], ne[N], cnt;
int siz[N], f[N];
bool ok[N];
namespace Wisadel
{inline void Wadd(int u, int v){to[++cnt] = v;ne[cnt] = hh[u];hh[u] = cnt;}inline void Wdfs(int u, int fa){siz[u] = 1;for(int i = hh[u]; i != -1; i = ne[i]){int v = to[i];Wdfs(v, u);siz[u] += siz[v];}}inline void Wck(int u, int tar){f[u] = 0;for(int i = hh[u]; i != -1; i = ne[i]){int v = to[i];Wck(v, tar);f[u] += f[v] + 1;}if(f[u] <= tar) f[u] = 0;else f[u] -= tar;}inline void Wsol(int u){if((u == 1 && f[u] != 1) || !f[u]) return ;if(f[u] == 1) ok[u] = 1;for(int i = hh[u]; i != -1; i = ne[i]){int v = to[i];Wsol(v);}}short main(){freopen("election.in", "r", stdin), freopen("election.out", "w", stdout);int T = qr;while(T--){n = qr;cnt = 0;fill(hh + 1, hh + 1 + n, -1);fo(i, 2, n){int x = qr;Wadd(x, i);}Wdfs(1, 0);int l = 1, r = n, ke = 0;while(l <= r){int mid = (l + r) >> 1;Wck(1, mid);if(f[1] == 0) r = mid - 1, ke = mid;else l = mid + 1;}memset(ok+1, 0, sizeof(bool)*n);Wck(1, ke - 1);Wsol(1);fo(i, 1, n){int zc = siz[i] - 1;if(zc > ke) putchar('1');else if(zc < ke) putchar('0');else printf("%d", ok[i]);}puts("");}return Ratio;}
}
signed main(){return Wisadel::main();}
// Now there's only one thing I can do
// Fight until the end like I promised to

邀请了 jijidawang 为特邀嘉宾帮助卡常,直接将一个 7000ms+ 的代码通过各种科技卡到了 accoder 上 1380ms。

jjdw 科技代码
// ubsan: undefined
// accoders
#include<bits/stdc++.h>
#define int unsigned
#define fo(x, y, z) for(int (x) = (y); (x) <= (z); (x)++)
#define fu(x, y, z) for(int (x) = (y); (x) >= (z); (x)--)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define lx ll
inline lx qr()
{char ch = getchar(); lx x = 0, f = 1;for(; ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;for(; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 3) + (x << 1) + (ch ^ 48);return x * f;
}
#undef lx
#define qr qr()
#define pii pair<int, int>
#define ppp pair<pii, pii>
#define fi first
#define se second
#define M_P(x, y) make_pair(x, y)
#define P_B(x) push_back(x)
constexpr int Ratio = 0;
constexpr int N = 1e6 + 5;
const int mod = 1e9 + 7;
int n;
int siz[N], f[N], qwq[N];
int ok[N];
namespace Wisadel
{vector<int> g[N];inline void Wadd(int u, int v){g[u].emplace_back(v);}inline void Wck(int u, signed tar){memset(f+1,0,sizeof(int)*n);#pragma GCC unroll 16for (int i=n; i>=2; i--){f[i] = max<signed>((signed)f[i] - tar, 0);f[qwq[i]] += f[i] + 1;}f[1] = max<signed>((signed)f[1] - tar, 0);}inline void Wsol(int u){if((u == 1 && f[u] != 1) || !f[u]) return ;if(f[u] == 1) ok[u] = 1;#pragma GCC unroll 2for (int v : g[u])Wsol(v);}inline __int32_t main(){freopen("election.in", "r", stdin), freopen("election.out", "w", stdout);int T = qr;while(T--){n = qr;#pragma GCC unroll 32for(int i=1;i<=n;i++)g[i].clear();#pragma GCC unroll 8for(int i=1;i<=n;i++){ok[i]=0;siz[i]=1;}#pragma GCC unroll 32fo(i, 2, n){qwq[i] = qr;Wadd(qwq[i], i);}#pragma GCC unroll 4fu(j, n, 2) siz[qwq[j]] += siz[j];int l = 1, r = n, ke = 0;while(l <= r){int mid = (l + r) >> 1;Wck(1, mid);if(f[1] == 0) r = mid - 1, ke = mid;else l = mid + 1;}Wck(1, ke - 1);Wsol(1);#pragma GCC unroll 32fo(i, 1, n){if(siz[i] - 1 > ke) putchar('1');else if(siz[i] - 1 < ke) putchar('0');else printf("%d", ok[i]);}puts("");}return Ratio;}
}
signed main(){return Wisadel::main();}
// Now there's only one thing I can do
// Fight until the end like I promised to

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

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

相关文章

[Moectf2024 ezMaze]

去壳 分析:迷宫分析10 * a2 - 10:Y (a1 - 1) / 8 :X 表示按字节处理迷宫迷宫以十六进制压缩,但迷宫是80 * 56的二进制迷宫 dump下来保存,转二进制,用bin(maze[2:]).zfill(8) 脚本(bfs): from collections import deque maze = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…

有理逼近AAA算法

用于有理逼近的AAA算法,可以有效防止伪极点现象用于有理逼近的AAA算法The AAA Algorithm for Rational Approximation, Yuji Nakatsukasa, Olivier Ste, and Lloyd N. Trefethen, SIAM Journal on Scientific Computing 2018 40:3, A1494-A1522, https://doi.org/10.1137/16M1…

Hgame2023 Reverse

Hgame 2023 [HGAME 2023 week1]test your IDA 用ida打开即可 [HGAME 2023 week1]encode 查壳 32位windows 加密函数将输入的字节转高位和低位进行加密,后与byte_403000进行比较 解密脚本: 这里采取了爆破 enc = [8, 6, 7, 6, 1, 6, 13, 6, 5, 6, 11, 7, 5, 6, 14, 6, 3, 6, 1…

[笔记]Dijkstra算法正确性证明

最近做了一些题,感觉对算法更深刻的理解是比套板子更深层次的,在这个层次上解决问题,思路会更加清晰。比如P5687 [CSP-S2019 江西] 网格图(题解)这道题就是网格图的最小生成树,解法就建立在普通Kruskal的基础上,当时想了挺久也没想出来,看了题解才豁然开朗。所以各算法…

企业搭建帮助中心:提升服务效率与客户满意度的双重优势

在当今快节奏的商业环境中,企业面临着日益增长客户服务需求。搭建一个有效的帮助中心,不仅能够提升服务效率,还能增强客户满意度,这对于企业的长期发展至关重要。本文将探讨企业搭建帮助中心的优势,并提供实用的策略。 在构建企业帮助中心的过程中,HelpLook作为一个强大的…

软件管理,磁盘存储,文件系统以及网络协议

目录硬盘存储术语CHS 磁盘存储管理 LVM RAID硬盘阵列 软件包管理 搭建私有yum仓库 系统安装之后的常用初始化步骤 OSI七层模型 linux端口的简单介绍 TCP简单介绍 ip地址分类硬盘存储术语CHShead:磁头 磁头数=盘面数 track:磁道 磁道=柱面数 sector:扇区,512bytes cylinder:…

【Capture one 2023软件下载与安装教程】

1、安装包 「Capture One 23」: 链接:https://pan.quark.cn/s/9ff0306530d1 提取码:xXDC 「Capture one22」: 链接:https://pan.quark.cn/s/34b723a4d6e1 提取码:gpM3 「Capture One 21」: 链接:https://pan.quark.cn/s/d65ea77ba33a 提取码:8A5D 2、安装教程(建议关闭杀…

[题解]P5687 [CSP-S2019 江西] 网格图

P5687 [CSP-S2019 江西] 网格图 简单来说题目就是给定一个\(n\times m\)的网格图,同行边权相同,同列边权相同,求该网格图的最小生成树。 根据Kruskal算法的贪心思想,我们要优先选择权值尽可能小的行,并将这条边应用于尽可能多的列。列方向同理。 为了保证最终生成树的连通…

鸿蒙NEXT自定义组件:太极Loading

【引言】(完整代码在最后面) 本文将介绍如何在鸿蒙NEXT中创建一个自定义的“太极Loading”组件,为你的应用增添独特的视觉效果。 【环境准备】 电脑系统:windows 10 开发工具:DevEco Studio NEXT Beta1 Build Version: 5.0.3.806 工程版本:API 12 真机:mate60 pro 语言:…

09C++选择结构(3)——教学

1、求3个整数中最小值; 2、3个数排序; 3、随机函数rand(); 4、if语句的应用; 5、bug与debug一、求3个整数中最小值 题目:输入三个整数,表示梨的重量,输出最小的数。 方法1:经过三次两两比较,得出最小值。 a<=b && a<=c min=ab<=c && b<=a…

趋动云—pycharm连接教程

一、创建项目 二、上传代码 三、启动趋动云虚拟环境四、连接pycharm 1. 打开pycharm,创建项目(上传代码),或者直接打开项目代码 2. 配置在线虚拟环境 (1)点击设置Settings->Python Interpreter->Add Interpreter->On SSH (2)新建在线虚拟环境连接 输入信息:…

校园AI语音识别霸凌监控系统

校园AI语音识别霸凌监控系统通过音频识别技术,校园AI语音识别霸凌监控系统针对校园内监控难以覆盖的区域,如厕所、宿舍、天台等,进行全天候的音频监控。系统通过识别特定的关键词,如“救命”、“老师救我”等,来监测可能发生的霸凌事件。系统采用YOLOv5 AI音频算法,该算法…