『模拟赛』多校A层冲刺NOIP2024模拟赛26

Rank

有点唐

image

A. 随机游走

签。

重要的就后两句话。题意由此转化成:到每一个节点时,先后遍历其所有子节点的子树,使得 \(\sum t_i\times w_i\) 最小。

提前 dfs 一遍处理出便利完某棵子树所需要的总时间和子树总价值,容易发现对于两个子节点的子树来说,全部遍历完所需总时间是一样的,所以只需考虑二者的先后关系。设子树 1/2 花费总时间和总价值分别为 \(t_1,t_2\)\(w_1,w_2\),容易发现若先遍历子树 1,则需要“多”消耗的代价为 \(t_1w_2\),反之先遍历子树 2 则代价为 \(t_2w_1\),显然选择代价小的更优,于是我们在求解每个点的子节点子树遍历顺序时按这个排序即可。时间复杂度最坏 \(\mathcal{O(n\log n)}\)

点击查看代码
#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;
#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 fi first
#define se second
#define pil pair<int, ll>
#define P_B(x) push_back(x)
#define pii pair<int, int>
#define M_P(x, y) make_pair(x, y)
const int Ratio = 0;
const int N = 5e5 + 5;
int n;
ll sumw[N], sumt[N], w[N << 1], a[N], ans;
int hh[N], to[N << 1], ne[N << 1], cnt;
vector<pil> son[N];
namespace Wisadel
{inline void Wadd(int u, int v, ll val){to[++cnt] = v;w[cnt] = val;ne[cnt] = hh[u];hh[u] = cnt;}inline void Wdfs(int u, int fa){sumw[u] = a[u];for(int i = hh[u]; i != -1; i = ne[i]){int v = to[i];if(v == fa) continue;son[u].P_B(M_P(v, w[i]));sumt[v] = w[i];Wdfs(v, u);sumw[u] += sumw[v];sumt[u] += sumt[v];}}inline void Wsol(int u, int fa, ll tim){ans += tim * a[u];if(!son[u].size()) return ;sort(son[u].begin(), son[u].end(), [](pil a, pil b){return sumw[a.fi] * sumt[b.fi] > sumw[b.fi] * sumt[a.fi];});for(pil v : son[u]){Wsol(v.fi, u, tim + v.se);tim += sumt[v.fi];}}short main(){freopen("walk.in", "r", stdin), freopen("walk.out", "w", stdout);n = qr;memset(hh, -1, sizeof hh);fo(i, 1, n - 1){int a = qr, b = qr;Wadd(i + 1, a, b), Wadd(a, i + 1, b);}fo(i, 1, n) a[i] = qr;Wdfs(1, 0);Wsol(1, 0, 0);printf("%lld\n", ans);return Ratio;}
}
signed main(){return Wisadel::main();}

B. 分发奖励

也比较签。其实九点左右就打完了,赛时由于调不出来树剖里一个唐错就先放了。

考虑一对存在祖先关系的点,容易发现如果祖先与某些点存在有一样的关系,那么子节点和这些点同样也存在有一样的关系。因此想到 dfs 同时统计答案。对于每个点搜索时统计这个点的贡献点,回溯时撤销这个点的贡献点即可。又因为本题中点和子树是捆绑关系,如果一个点被统计过有贡献,则其子树整体也一定有贡献。所以加入时判断是否被统计过,撤销时只用撤新加入的贡献点即可。

赛时写法大概率是可以被卡的,构造一棵一半是菊花一半是链的树就会爆炸。所以考虑优化,也比较简单,上一棵线段树即可。求出所有点的 dfs 序及其回溯边界,将树拍成序列在线段树上操作,复杂度就是稳定的 \(\mathcal{O(n\log n)}\)不过不是很想写了所以放原代码。

点击查看代码
#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;
#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 fi first
#define se second
#define pil pair<int, ll>
#define P_B(x) push_back(x)
#define pii pair<int, int>
#define M_P(x, y) make_pair(x, y)
const int Ratio = 0;
const int N = 5e5 + 5;
int n, m;
int siz[N], son[N], dep[N], fx[N], top[N];
int hh[N], to[N << 1], ne[N << 1], cnt;
int ans[N];
bool vis[N], yz[N];
set<int> st[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){siz[u] = 1, dep[u] = dep[fx[u]] + 1;for(int i = hh[u]; i != -1; i = ne[i]){int v = to[i];fx[v] = u;Wdfs(v);siz[u] += siz[v];if(siz[v] > siz[son[u]]) son[u] = v;}}inline void Wdfs2(int u, int tpf){top[u] = tpf;if(son[u]) Wdfs2(son[u], tpf);for(int i = hh[u]; i != -1; i = ne[i]){int v = to[i];if(v == son[u]) continue;Wdfs2(v, v);}}inline int Wq(int u, int v){if(top[u] == top[v]) return dep[u] > dep[v] ? v : u;if(dep[u] < dep[v]) swap(u, v);while(top[u] != top[v]){if(dep[u] <= dep[v]) return -1;if(u == top[u]) u = fx[u];else u = top[u];}return v;}int stk[N << 1], tp;inline int Wshua(int u){if(yz[u]) return 0;yz[u] = 1;stk[++tp] = u;int res = 1;for(int i = hh[u]; i != -1; i = ne[i]){int v = to[i];res += Wshua(v);}return res;}inline void Wsol(int u, int now){stk[++tp] = -u;if(st[u].size()) now += Wshua(u);for(int vv : st[u]){if(vis[vv] || yz[vv]) continue;now += Wshua(vv);}ans[u] = now - yz[u];for(int i = hh[u]; i != -1; i = ne[i]){int v = to[i];Wsol(v, now);}while(stk[tp] != -u) yz[stk[tp]] = 0, tp--, now--;tp--;}short main(){freopen("reward.in", "r", stdin), freopen("reward.out", "w", stdout);n = qr, m = qr;memset(hh, -1, sizeof hh);fo(i, 2, n){int a = qr;Wadd(a, i);}Wdfs(1), Wdfs2(1, 1);fo(i, 1, m){int a = qr, b = qr;if(a == b) st[a].insert(a);else{int op = Wq(a, b);if(op == -1) st[a].insert(b), st[b].insert(a);else st[op].insert(op);}}if(st[1].size()){fo(i, 1, n) printf("%d ", n);return Ratio;}Wsol(1, 0);fo(i, 1, n) printf("%d ", ans[i]);return Ratio;}
}
signed main(){return Wisadel::main();}

C. 卡路里

题面自相矛盾懒得说了,线上和本机测评差半秒是什么鬼。

题面就得倒着看,前面说的和要求的是两码事。转换后的题意可以理解为选择一段区间 \([l,r],1\le l\le r\le m\) 内的点,点之间有负边权,取选中的点中 \(n\) 个元素的最大值之和,最大化最大值之和与边权之和。\(\mathcal{O(nm^2)}\) 很好想啊,枚举两点作为左右边界扫一遍就做完了,然后本机跑 \(n=200,m=5000\) 只用 0.6s?怎么算怎么复杂度不对,但是出于信任加了个循环展开直接交了,结果 35pts。

考虑正解。考虑到选定一个区间有哪些项会有贡献,比较显然是其中 \(n\) 个元素分别的最大值所在位置。考虑枚举右端点,首先要在所有左端点上加上到当前点的边权的负贡献,那么对每个元素来说,当前点会产生贡献的左端点一定是从上一个不大于自身的点到当前点,容易想到单调栈维护,此时这一段该元素的取值一定取当前点优,给这些位置删去原贡献加上当前点贡献即可。依次操作这 \(n\) 种元素,最终以当前点为右端点的最大值就是以前面所有点为左端点时贡献的最大值。发现本质上是区间修改和区间最大值的操作,直接上线段树即可。时间复杂度 \(\mathcal{O(nm\log m)}\)

点击查看代码
#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;
#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 fi first
#define se second
#define pil pair<int, ll>
#define P_B(x) push_back(x)
#define pii pair<int, int>
#define M_P(x, y) make_pair(x, y)
const int Ratio = 0;
const int N = 200 + 5, M = 5000 + 5;
int n, m;
ll d[M];
ll a[M][N], v[M << 2], lazy[M << 2], st[N][M], top[N];
namespace Wisadel
{#define ls (rt << 1)#define rs (rt << 1 | 1)#define mid ((l + r) >> 1)inline void Wpushup(int rt){v[rt] = max(v[ls], v[rs]);}inline void Wpushdown(int rt){v[ls] += lazy[rt], v[rs] += lazy[rt];lazy[ls] += lazy[rt], lazy[rs] += lazy[rt];lazy[rt] = 0;}inline void Wupd(int rt, int l, int r, int x, int y, ll k){if(x <= l && r <= y){v[rt] += k, lazy[rt] += k;return ;}if(lazy[rt]) Wpushdown(rt);if(x <= mid) Wupd(ls, l, mid, x, y, k);if(y > mid) Wupd(rs, mid + 1, r, x, y, k);Wpushup(rt);}inline ll Wq(int rt, int l, int r, int x, int y){if(x <= l && r <= y) return v[rt];if(lazy[rt]) Wpushdown(rt);ll res = -2e18;if(x <= mid) res = max(res, Wq(ls, l, mid, x, y));if(y > mid) res = max(res, Wq(rs, mid + 1, r, x, y));return res;}short main(){freopen("calorie.in", "r", stdin), freopen("calorie.out", "w", stdout);n = qr, m = qr;fo(i, 1, m - 1) d[i] = qr;fo(i, 1, m) fo(j, 1, n) a[i][j] = qr;ll ans = -2e18;fo(i, 1, m){if(i != 1) Wupd(1, 1, m, 1, i - 1, -d[i - 1]);fo(j, 1, n){while(top[j] && a[st[j][top[j]]][j] < a[i][j]){Wupd(1, 1, m, st[j][top[j] - 1] + 1, st[j][top[j]], -a[st[j][top[j]]][j]);top[j]--;}Wupd(1, 1, m, st[j][top[j]] + 1, i, a[i][j]);st[j][++top[j]] = i;}ans = max(ans, Wq(1, 1, m, 1, i));}printf("%lld\n", ans);return Ratio;}
}
signed main(){return Wisadel::main();}

D. 传话游戏

不会。12pts 暴力挂了。

正解用到拉插。

倒数第三场模拟赛,又是全真模拟,换了座。

开场半小时切签,然后半小时会 T2,出现唐错果断开 T3 换脑子,然后发现暴力可过,然后回来再看 T2 一眼找出错。此时只过了 3h,当时以为顺飞了,然后 all in T4 上,1.5h 拿到 0pts 的高分。

感觉策略是出了一点问题的,尤其是 T4,不应该在看一眼不会暴力的情况下不留检查时间的。哪怕留出半个小时给 T3 优化也能打出来,就不至于挂到 35pts 了。然后就是树剖又又写挂,这次挂的是判祖先关系,不能直接跳 fa[top[u]],可能会出现 v=top[u] 然后直接跳过了的情况导致判错。复杂度也不对,得亏是数据没有狠卡,想想写个优化上去也耽误不了多长时间,只是没有心塌下去将程序不断优化。

这两天要复习的,字符串(哈希和 kmp 感觉要不是最近光做到就忘完了),线段树合并(学的时候几乎全是硬焯),平衡树(真考吗,不过起码看看 fhq),tarjan 相关(不熟,但怕真考到),最短路(忘),差分约束,矩阵,树状数组扩展,exgcd。。。byd 怎么这么多

但是说到底,考前心态放平最重要,考场上尽力就好,不要因为没有快切签到而焦急,也不能因为切得太快而放飞自我,塌下心来最重要,平和,坦然。

下午冒险又打了会篮球,怕高强度所以打了会半场,后来人越来越多就扩成全场了,比前几次少了单带和快攻,多了 n 次投不中的篮(

天气越来越冷了,不知道燕大机房有没有空调。


完结撒花~

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

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

相关文章

强化学习交易应用相关

FinRL尝试 这是第一个开源的金融强化学习框架,FinRL已经发展成为一个包含丰富资源的生态系统,为金融强化学习的研究和应用提供了强大的支持。 项目地址:https://github.com/AI4Finance-Foundation/FinRL个人使用体验:可能因为维护不及时,示例代码无法顺利运行,需要各种修…

24. 两辆交换链表中的节点

题目 卡哥的讲解很详细了 卡哥视频讲解一如既往的把小细节都讲到了 跟着卡哥的代码敲了下 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next…

jenkins搭建和使用_(17)

Jenkins操作手册 =================================================================== 一、jenkins介绍 1、持续集成(CI) Continuous integration 持续集成 团队开发成员每天都有集成他们的工作,通过每个成员每天至少集成一次,也就意味着一天有可 能多次集成。在工作中我…

Notepad++ 使用技巧

下载 Notepad++ 打开浏览器,前往 Notepad++ 的官方网站:Notepad++点我下载 常用快捷键 以下是一些常用的 Notepad++ 快捷键: Ctrl + N:新建一个文件 Ctrl + O:打开一个文件 Ctrl + S:保存当前文件 Ctrl + Shift + S:另存为 Ctrl + P:打印文件 Ctrl + Z:撤销上一步操作…

LeetCode 367[有效的完全平方数]

LeetCode 367[有效的完全平方数]题目 链接 LeetCode 367[有效的完全平方数] 详情实例提示题解 思路 求算术平方根,逐渐遍历的话,数值小应该是没问题的,但是数值大的话时间应该会超出限制 本质是:给定一个数字,在范围内找一个数字的平方为该数,找到了则输出ture,找不到则…

使用 Visual Studio Code 写网页

1、Visual Studio Code双击打开后 ,点击圈主的部分(资源管理器) 会出现 “打开文件夹” 2、点击 “打开文件夹” ,选中想要打开的文件夹 ,点击选择文件 也可以直接拖拽 想要打开的 文件夹 放进来3、可以看道文件夹里面的东西都进来了 之前我们写的 网页 代码 也在这里 可…

WPF 粉笔绘制

在做白板书写的时候,会有各种笔的绘制,比如 书写笔、马克笔、演示笔等等。粉笔的功能需求也是很有必要的。 上网搜了一圈,几乎没有绘制粉笔的。 有的是毛笔、楷体等绘制的如下博客: wpf inkcanvas customink 毛笔效果_wpf inkcanvas 笔锋-CSDN博客 【WPF】 InkCanvas 书写毛…

鸿蒙NEXT开发案例:温度转换

【引言】 温度是日常生活中常见的物理量,但不同国家和地区可能使用不同的温度单位,如摄氏度(Celsius)、华氏度(Fahrenheit)、开尔文(Kelvin)、兰氏度(Rankine)和列氏度(Reaumur)。为了方便用户在这些温度单位之间进行快速准确的转换,我们开发了一款温度转换工具。…

团队项目-7

一、昨日已完成的任务 前后端交互,调用接口完成页面。导入数据等 今日计划完成的任务 继续做好功能,测试运行 工作中遇到的困难 测试运行时出现不少问题,服务器连不上等问题 项目迁入记录代码:总结 一周的学习收获良多,项目实战难度大的同时也给了我们很多动力,是一次珍贵…

windows安全中心,永久卸载工具

使用方法 2024Goby红队版工具分享,附2024年漏洞POC下载 下载链接: https://pan.quark.cn/s/4fc2712a2afc一路回车,选项Y即可耐心等待几秒种,自动重启此时打开windows安全中心,已经完全不能使用了,响应的杀毒功能也关了往期推荐 【渗透测试】DC1~9(全) Linux提权靶机渗透教…

团队项目-6

一、昨日已完成的任务 学习有关springboot,vue等前后端知识,完善数据库和底层框架,学习有关知识,继续做功能接口。今日计划完成的任务 前后端交互,调用接口完成页面。导入数据等 工作中遇到的困难 目前调用接口出现问题,接口有些错误 代码迁入记录项目模块与代码总结 时间…

CTF学习(18)MISC(面具下的flag)

1.解压文件后发现是.wav格式的文件--->使用audacity打开后发现存在摩斯电码摩斯电码: ..... -... -.-. ----. ..--- ..... -.... ....- ----. -.-. -... ----- .---- ---.. ---.. ..-. ..... ..--- . -.... .---- --... -.. --... ----- ----. ..--- ----. .---- ----. .---…