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

Rank

还行

image

A. 传送 (teleport)

签。

单元最短路,先想 Dijkstra。发现这道题还有个不同寻常的移动方式,可以以 \(min\left(|x_i-x_j|,|y_i-y_j|\right)\) 的代价从 \(i\) 移动到 \(j\)。暴力连边是 \(\mathcal{O(n^2)}\) 的,时间空间都过不去。

被叫去整内务在楼梯上想到,一个点不应该来回走,于是想到若有 \(x_i<x_j<x_k\) (假设纵坐标不优),那么我们只用连 \(i\rightarrow j\)\(j\rightarrow k\) 这两条边即可。因此想到分别按横坐标和纵坐标给点排序,然后连接相邻的两点,再去跑 dij 即可。坐标共 \(2\times \left(n-1\right)\) 条边,由于是无向图,我们边的内存应该开 \(n\) 的 6 倍。时间复杂度仍是 \(\mathcal{O(n\log n)}\) 的。喜提最优解。

点击查看代码
#include<bits/stdc++.h>
#define fo(x, y, z) for(register int (x) = (y); (x) <= (z); (x)++)
#define fu(x, y, z) for(register 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 pii pair<int, int>
#define M_P(a, b) make_pair(a, b)
#define fi first
#define se second
#define P_B(x) push_back(x)
const int Ratio = 0;
const int N = 2e5 + 5;
int n, m;
int hh[N], to[N << 3], ne[N << 3], w[N << 3], cnt;
ll dis[N];
bool yz[N];
struct rmm
{ll dis; int u;bool operator < (const rmm &a) const {return a.dis < dis;}
};
struct nd
{int id, x, y;
} d[N], dd[N];
namespace Wisadel
{void Wadd(int u, int v, int val){to[++cnt] = v;w[cnt] = val;ne[cnt] = hh[u];hh[u] = cnt;}void Wdij(int x){priority_queue<rmm> q;memset(dis, 0x3f, sizeof dis);dis[x] = 0;q.push({0, x});while(q.size()){int u = q.top().u; q.pop();if(yz[u]) continue;yz[u] = 1;for(int i = hh[u]; i != -1; i = ne[i]){int v = to[i];if(dis[v] > dis[u] + w[i]){dis[v] = dis[u] + w[i];q.push({dis[v], v});}}}}short main(){freopen("teleport.in", "r", stdin) , freopen("teleport.out", "w", stdout);// freopen(".err", "w", stderr);n = qr, m = qr;memset(hh, -1, sizeof hh);fo(i, 1, n) dd[i].x = d[i].x = qr, dd[i].y = d[i].y = qr, d[i].id = dd[i].id = i;sort(d + 1, d + 1 + n, [](nd a, nd b){return a.x < b.x;});sort(dd + 1, dd + 1 + n, [](nd a, nd b){return a.y < b.y;});fo(i, 1, n - 1){int c1 = d[i + 1].x - d[i].x, c2 = dd[i + 1].y - dd[i].y;Wadd(d[i].id, d[i + 1].id, c1), Wadd(d[i + 1].id, d[i].id, c1);Wadd(dd[i].id, dd[i + 1].id, c2), Wadd(dd[i + 1].id, dd[i].id, c2);}fo(i, 1, m){int a = qr, b = qr, c = qr;Wadd(a, b, c), Wadd(b, a, c);}Wdij(1);fo(i, 2, n) printf("%lld ", dis[i]);puts("");return Ratio;}
}
signed main(){return Wisadel::main();}

B. 排列 (permutation)

组合数学水题,状压 dp 也能做。

赛时发现不会插板法,于是选择分讨打表,但是到 \(\frac{n}{k}\ge 8\) 因为没有暴力帮忙核对导致漏情况了,血亏。调出来复杂度就是 \(\mathcal{O(n)}\) 的预处理,\(\mathcal{O(1)}\) 出答案。

发现只有 \(\lfloor{}\frac{n}{k}\rfloor{}\) 个数是有用的,其余的数无论如何放均不会产生 \(k\) 的 gcd。不过特殊的是,当 \(\frac{n}{k}\ge 4\) 时,总有一些数放在一起会产生 \(\gt k\) 的 gcd。因此我们考虑全排列枚举这 \(\lfloor{}\frac{n}{k}\rfloor{}\) 个数,记录它们间的 gcd 为 \(k\) 的个数,然后用插板法求这 \(\lfloor{}\frac{n}{k}\rfloor{}\) 个数的合法方案,最后乘上 \(n-\lfloor{}\frac{n}{k}\rfloor{}\) 的排列即为最终答案,复杂度大概是 \(\mathcal{O(\lfloor{}\frac{n}{k}\rfloor{}!\times \lfloor{}\frac{n}{k}\rfloor{}+n)}\) 的。

由于放不下赛时的做法,遂在正解中用了数据点分治。

点击查看代码
#include<bits/stdc++.h>
#define fo(x, y, z) for(register int (x) = (y); (x) <= (z); (x)++)
#define fu(x, y, z) for(register 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 pii pair<int, int>
#define M_P(a, b) make_pair(a, b)
#define fi first
#define se second
#define P_B(x) push_back(x)
const int Ratio = 0;
const int N = 3e4 + 5, M = 3000;
const int mod = 998244353;
int n, k;
int a[N];
ll jc[N], ny[N];
namespace Wisadel
{ll Wqp(ll x, int y){ll res = 1;while(y){if(y & 1) res = res * x % mod; x = x * x % mod; y >>= 1;}return res;}ll Wc(int n, int m){return jc[n] * ny[m] % mod * ny[n - m] % mod;}short main(){freopen("permutation.in", "r", stdin) , freopen("permutation.out", "w", stdout);// freopen(".err", "w", stderr);n = qr, k = qr;jc[0] = ny[0] = 1;fo(i, 1, n) jc[i] = jc[i - 1] * i % mod;ny[n] = Wqp(jc[n], mod - 2);fu(i, n - 1, 1) ny[i] = ny[i + 1] * (i + 1) % mod;ll zc = n / k;ll ans = 1;if(zc <= 3) ans = jc[zc] * jc[n - zc] % mod * Wc(n - zc + 1, zc) % mod;else if(zc <= 5){ans = jc[zc] * jc[n - zc] % mod * Wc(n - zc + 1, zc) % mod;ans = (ans + jc[zc - 1] * jc[n - zc] % mod * 2 * Wc(n - zc + 1, zc - 1) % mod) % mod;}else if(zc <= 7){ans = jc[zc] * jc[n - zc] % mod * Wc(n - zc + 1, zc) % mod;ans = (ans + jc[zc - 1] * jc[n - zc] % mod * 2 % mod * Wc(n - zc + 1, zc - 1) % mod * 4 % mod) % mod;ans = (ans + jc[zc - 2] * jc[n - zc] % mod * 6 % mod * Wc(n - zc + 1, zc - 2) % mod) % mod;ans = (ans + jc[zc - 2] * jc[n - zc] % mod * 4 % mod * Wc(n - zc + 1, zc - 2) % mod) % mod;ans = (ans + jc[zc - 2] * jc[n - zc] % mod * 2 % mod * Wc(n - zc + 1, zc - 2) % mod * 2 % mod) % mod;ans = (ans + jc[zc - 3] * jc[n - zc] % mod * 4 % mod * Wc(n - zc + 1, zc - 3) % mod) % mod;}else{ans = 0;fo(i, 1, zc) a[i] = i;do{int cnt = 0;fo(i, 1, zc - 1) if(__gcd(a[i], a[i + 1]) == 1) cnt++;ans = (ans + Wc(n - cnt, zc)) % mod;} while(next_permutation(a + 1, a + 1 + zc));ans = ans * jc[n - zc] % mod;}printf("%lld\n", ans);return Ratio;}
}
signed main(){return Wisadel::main();}

C. 战场模拟器 (simulator)

没学过势能线段树,不知道这样复杂度是正确的,遂没敢打,只打了 Subtask2 的 23pts。

发现这道题主要是死人不复活和护盾比较 ex,因此我们针对这两点直接暴力做就好。如果你打了 Subtask2,那么应该知道为什么要记录区间最小生命值及其数量,没打也能懂:因为每次扣血操作我们是暴力进行的,只有求濒死人数才用到最小值且只用到最小值。然后记录区间死亡人数,以及一个 lazy tag。我们发现,当区间没有盾并且打不死最小生命的英雄时我们没必要递归到单点做,因此再记录一个区间盾数量。

除了扣血,其它操作都是基本的线段树操作。在求濒死人数时还可以根据当前最小值是否 \(\gt 0\) 来节省递归的次数。

问题主要在证明这个做法的时间复杂度正确性,搜索发现并没有太好的讲解。于是只能感性理解:每个点的操作都是有上限的,在达到这个上限后便不用再进行单点修改,这样就保证了均摊复杂度。求复杂度好像用到了势能函数,不会,只给出结果:\(\mathcal{O(n\log n + 4n\log (势能))}\)。本题的复杂度是 \(\mathcal{O(n\log n+q\log n)}\) 的。

点击查看代码
#include<bits/stdc++.h>
#define fo(x, y, z) for(register int (x) = (y); (x) <= (z); (x)++)
#define fu(x, y, z) for(register 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 pii pair<int, int>
#define M_P(a, b) make_pair(a, b)
#define fi first
#define se second
#define P_B(x) push_back(x)
const int Ratio = 0;
const int N = 2e5 + 5, M = 3000;
const int mod = 998244353;
int n, m;
int a[N];
int a1[N << 2], dun[N << 2], num[N << 2];
ll s[N << 2], lazy[N << 2];
namespace Wisadel
{#define ls (rt << 1)#define rs (rt << 1 | 1)#define mid ((l + r) >> 1)void Wpushup(int rt){a1[rt] = a1[ls] + a1[rs];dun[rt] = dun[ls] + dun[rs];s[rt] = min(s[ls], s[rs]);num[rt] = 0;if(s[ls] == s[rt]) num[rt] += num[ls];if(s[rs] == s[rt]) num[rt] += num[rs];}void Wpushdown(int rt){s[ls] += lazy[rt], s[rs] += lazy[rt];lazy[ls] += lazy[rt], lazy[rs] += lazy[rt];lazy[rt] = 0;}void Wbuild(int rt, int l, int r){if(l == r){s[rt] = a[l];num[rt] = 1;return ;}Wbuild(ls, l, mid), Wbuild(rs, mid + 1, r);Wpushup(rt);}void Watk(int rt, int l, int r, int x, int y, int k){if(x <= l && r <= y && s[rt] >= k && !dun[rt]){s[rt] -= k, lazy[rt] -= k;return ;}if(l == r){if(dun[rt]) dun[rt]--;else a1[rt] = 1, num[rt] = 0, s[rt] = 4e18;return ;}if(lazy[rt]) Wpushdown(rt);if(x <= mid) Watk(ls, l, mid, x, y, k);if(y > mid) Watk(rs, mid + 1, r, x, y, k);Wpushup(rt);}void Wrec(int rt, int l, int r, int x, int y, int k){if(x <= l && r <= y){s[rt] += k, lazy[rt] += k;return ;}if(lazy[rt]) Wpushdown(rt);if(x <= mid) Wrec(ls, l, mid, x, y, k);if(y > mid) Wrec(rs, mid + 1, r, x, y, k);Wpushup(rt);}void Wdun(int rt, int l, int r, int x){if(l == r){dun[rt]++;return ;}if(lazy[rt]) Wpushdown(rt);if(x <= mid) Wdun(ls, l, mid, x);else Wdun(rs, mid + 1, r, x);Wpushup(rt);}int Wq1(int rt, int l, int r, int x, int y){if(x <= l && r <= y) return a1[rt];if(lazy[rt]) Wpushdown(rt);int res = 0;if(x <= mid) res += Wq1(ls, l, mid, x, y);if(y > mid) res += Wq1(rs, mid + 1, r, x, y);return res;}int Wq2(int rt, int l, int r, int x, int y){if(s[rt]) return 0;if(x <= l && r <= y) return num[rt];if(lazy[rt]) Wpushdown(rt);int res = 0;if(x <= mid) res += Wq2(ls, l, mid ,x, y);if(y > mid) res += Wq2(rs, mid + 1, r, x, y);return res;}short main(){freopen("simulator.in", "r", stdin) , freopen("simulator.out", "w", stdout);// freopen(".err", "w", stderr);n = qr;fo(i, 1, n) a[i] = qr;Wbuild(1, 1, n);m = qr;fo(i, 1, m){int op = qr, l = qr, r, k;if(op == 1) r = qr, k = qr, Watk(1, 1, n, l, r, k);else if(op == 2) r = qr, k = qr, Wrec(1, 1, n, l, r, k);else if(op == 3) Wdun(1, 1, n, l);else if(op == 4) r = qr, printf("%d\n", Wq1(1, 1, n, l, r));else r = qr, printf("%d\n", Wq2(1, 1, n, l, r));}return Ratio;}
}
signed main(){return Wisadel::main();}

D. 点亮 (light)

还不会,咕咕咕。

在回了趟宿舍的干扰下打成这样感觉还行,甚至对 T1 起了正向帮助,那么______🤔🤔🤔

T2 属实是钻死胡同里去了,分讨了 2h+,策略失误,在纠正了数据点的问题后拿到 50pts,但没时间打 T3 了,想到的暴力做法就是正解却没打,血亏。

狂补组合数学。


完结撒花~

复活了。

image

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

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

相关文章

一、STM32F103C8T6--GPIO

STM32f103c8t6 32位Cortex-M3内核 RISC处理器,最高主频72MHZ,Flash:64KB,SRAM:20KB 片上外设: I/O端口:多达37个GPIO引脚(支持复用功能)。 GPIO 端口支持输入、输出、上拉/下拉功能。定时器:3 个 16 位通用定时器(支持 PWM 输出)。******** 1 个高级定时器(支持多通…

订阅

订阅权限配置类型 来源 备注订阅消息 微信后台开通 必需消息推送 微信后台开通 必需官方文档链接:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/subscribe-message.html相关权限设置: 一:登录微信后台,选择开发管理,启用消息推送。二:选择订…

cornerstone中RAFT的buffer的实现

1.概览: 谈到raft协议实现就绕不开网上流行的mit6.824,但其为go语言,官方没有lab的答案,框架也很晦涩难懂,且全网没有一个博客对其有清晰的解释,有的只是甩一堆名词然后直接贴没有任何注释的代码,非常不适合学习。 但是github上面的cornerstone是纯c++实现的一个非常优雅…

Dbeaver24.2.2安装和使用教程(免费的数据库管理工具)

前言 DBeaver是免费和开源(GPL)为开发人员和数据库管理员通用数据库工具。 DBeaver 通过 JDBC 连接到数据库,可以支持几乎所有的数据库产品,包括:MySQL、PostgreSQL、MariaDB、SQLite、Oracle、Db2、SQL Server、Sybase、MS Access、Teradata、Firebird、Derby 等等。 下载…

支付

支付权限配置类型 来源 备注虚拟支付 微信后台开通 必需微信支付 微信后台开通 必需虚拟支付设置:官方文档链接:https://developers.weixin.qq.com/minigame/dev/guide/open-ability/virtual-payment/virtual-payment2.html一:进入微信后台,进入虚拟支付模块,看到右上角出…

五款实用GIS工具箱推荐,帮你轻松搞定各类GIS问题

1. GISBox 简介:GISBox 是一款集成化的GIS工具箱,能够进行GIS影像、地形和倾斜摄影的实时编辑、格式转换和服务发布。它支持多种GIS文件格式的转换,并且允许用户免费发布影像、地形和倾斜摄影服务。 优点:免费服务发布:支持 3DTiles、Terrain、WMTS 等协议发布,且不收取费…

Rider设置

自动换行强制换行&换行线 (设置成0)设置自定义背景色保存自动格式化代码格式化可以自定义,格式化范围也可以自定义

数据采集与融合技术作业2

作业2我的getee仓库链接 https://gitee.com/LLLzt-III/crawl_project 作业1代码链接 https://gitee.com/LLLzt-III/crawl_project/tree/master/作业2一、作业①:要求:在中国气象网(http://www.weather.com.cn)给定城市集的7日天气预报,并保存在数据库。 输出信息:Gitee文件…

Qt cmake修改.exe程序图标

1。在项目根目录创建一个 app.rc 文件,文件内容 IDI_ICON1 ICON DISCARDABLE "logo.ico"。 2。准备一个.ico 文件放到项目根目录(这个文件不可以直接用 .png .jpg 改后缀,可以通过网络工具转成 .ico 文件)。 3。将.ico文件在QT项目里的.qrc资源里加入(.qrc文件需…

第147篇:微信小程序开发中Promise的使用(aysnc,await)

好家伙,0.错误描述 今天在开发中犯了一个比较严重的错误 对于Promise的错误使用场景: 微信小程序中展示搜索条件列表// API请求工具函数 const apiRequest = (url, method = GET, headers = {}) => {return new Promise((resolve, reject) => {wx.request({url,method,he…

Playable Director

目录组件介绍字段说明使用Timeline资源 组件介绍Unity原生组件,Playable Director 组件存储时间轴实例和时间轴资源之间的链接。Playable Director 组件控制时间轴实例的播放时间、时间轴实例更新其时钟的方式以及在时间轴实例完成播放后发生的操作。字段说明playable TimeLin…