2023/11/15 NOIP 模拟赛
T1 游戏
标签
尺取 线段树 单调队列
线段树进阶
思路
抽象题意,相当于有 \(t\) 个点,有 \(n\) 个下接 \(x\) 轴的矩形。
首先明显可以按照 \(c\) 排序,然后尺取。
写法
线段树记录每区间内未被覆盖的最大高度。
因为插入和删除的顺序相对不变,一个单调队列维护该区间内矩形高度即可,若有删除操作则向儿子取 \(\max\) 重新计算 \(mx\)。
代码
常数极大,可使用内存池优化。
code
ci N = 1e6 + 9;
ci inf = 2e9;
int t, n, ans(inf);
int a[N], b[N], c[N], v[N], h[N], id[N];
bool cmp(int x, int y) {return c[x] < c[y];}
struct SGT {
#define lc ((u) << 1)
#define rc ((u) << 1 | 1)
int mx[N << 2], buf[N * 40];
unsigned int head[N << 2], tail[N << 2];
il void pushup_mx(int u) {
if(head[u] > tail[u]) return;
if(v[q[u][head[u]]] >= mx[u]) mx[u] = 0;
}
il void pushup(int u) {
mx[u] = max(mx[lc], mx[rc]);
pushup_mx(u);
}
il void build(int u, int l, int r) {
if(l == r) return mx[u] = h[l], void();
int mid = (l + r) >> 1;
build(lc, l, mid);
build(rc, mid + 1, r);
pushup(u);
}
il void insert(int u, int l, int r, int a, int b, int i) {
if(a <= l && r <= b) {
while(head[u] < q[u].size() && v[*(-- q[u].end())] <= v[i]) q[u].pop_back();
q[u].eb(i);
if(v[q[u][head[u]]] >= mx[u]) mx[u] = 0;
return;
}
if(b < l || r < a) return;
int mid = (l + r) >> 1;
insert(lc, l, mid, a, b, i);
insert(rc, mid + 1, r, a, b, i);
pushup(u);
}
il void erase(int u, int l, int r, int a, int b, int i) {
if(a <= l && r <= b) {
if(q[u][head[u]] == i) {
++ head[u];
if(l == r) {
mx[u] = h[l];
pushup_mx(u);
}
else {
pushup(u);
}
}
return;
}
if(b < l || r < a) return;
int mid = (l + r) >> 1;
erase(lc, l, mid, a, b, i);
erase(rc, mid + 1, r, a, b, i);
pushup(u);
}
} tree;
il void ins(int i) {
tree.insert(1, 1, t, a[i], b[i], i);
}
il void ers(int i) {
tree.erase(1, 1, t, a[i], b[i], i);
}
int main() {
freopen("game.in", "r", stdin);
freopen("game.out", "w", stdout);
rd(t); rd(n);
rep(i, 1, n) {
rd(a[i], b[i], c[i], v[i]);
id[i] = i;
}
sort(id + 1, id + n + 1, cmp);
rep(i, 1, t) rd(h[i]);
tree.build(1, 1, t);
int L = 1;
rep(_i, 1, n) {
int i = id[_i];
ins(i);
while(tree.mx[1] == 0) {
cmin(ans, c[i] - c[id[L]]);
ers(id[L]); ++ L;
}
}
pt("%d\n", ans);
return 0;
}
T2 驻军
标签
长链剖分,树上前缀和进阶
思路
订正的时候没有对答案取模再乘,dfs 时没有判长链。
考虑将找链转化为对端点处理,发现可以通过处理将答案变为只与 \(lca(x, y), x, y\) 有关的形式,这样才能进行长链剖分。
约定
\(f_u\) 表示 \(u\) 子树内所有点到 \(u\) 的距离和。
\(e_{u, v}\) 表示 \((u\to v)\) 的边权。
\(h_u\) 表示 \(u\) 子树外所有点到 \(u\) 的距离和。
\(sz_u\) 表示 \(u\) 子树的大小。
\(w_v\) 表示 \((fa_v\to v)\) 的贡献,等于 \(sz_v\cdot e_{fa_v, v}\)。
\(s_u\) 表示从 \(u\) 到根(可设为 \(1\))的简单路径上的边的 \(w\) 之和,等于 \(w_u + w_{fa_u} + \cdots\)
转移
若路径为 \(x, y\),设 \(lca(x, y) = u\) 则答案为 \(h_u + f_u - (s_x - s_u) - (s_y - s_u)\)。
这个比较难,可对每条边快速统计多算的贡献,减去即可。
\(f_u = \sum\limits_{u\to v} (f_v + w_v)\)
\(s_v = s_u + w_v\)
\(h_v = (n - sz_v)\cdot e_{u, v} + h_u + f_u - f_v - w_v\)
代码
code
ci N = 2e6 + 9;
const ll INF = 1e18;
int n, k;
ll sz[N], f[N], s[N], h[N], w[N];
vector<pii> A[N];
void dfs1(int u, int la) {
sz[u] = 1;
for(pii e : A[u]) {
int v = e.fi;
if(v == la) continue;
dfs1(v, u);
sz[u] += sz[v];
w[v] = sz[v] * e.se;
f[u] += f[v] + w[v];
}
}
int depth[N], son[N];
void dfs2(int u, int la) {
depth[u] = 1;
for(pii e : A[u]) {
int v = e.fi;
if(v == la) continue;
s[v] = s[u] + w[v];
h[v] = 1LL * (n - sz[v]) * e.se + h[u] + (f[u] - f[v] - w[v]);
dfs2(v, u);
cmax(depth[u], depth[v] + 1);
if(depth[v] + 1 == depth[u]) son[u] = v;
}
}
ll buc[N], *mx[N], ans(INF);
void dfs(int u, int la) {
mx[u][1] = s[u];
if(son[u]) {
mx[son[u]] = mx[u] + 1;
dfs(son[u], u);
for(pii e : A[u]) {
int v = e.fi;
if(v == la || v == son[u]) continue;
mx[v] = mx[u] + depth[u];
dfs(v, u);
rep(i, 1, depth[v]) {
if(i > 0 && k - i > 1 && i <= depth[v] && k - i <= depth[u]) {
cmin(ans, h[u] + f[u] + 2 * s[u] - mx[u][k - i] - mx[v][i]);
if(ans < 0) {
printf("%lld %lld %lld\n", h[u], f[u], s[u]);
printf("u-road = %d v = %d\n", u, v), exit(0);
}
}
}
rep(i, 1, depth[v]) cmax(mx[u][i + 1], mx[v][i]), mx[v][i] = 0;
}
}
if(depth[u] >= k) {
cmin(ans, h[u] + f[u] + s[u] - mx[u][k]);
if(ans < 0) printf("u-list = %d\n", u),exit(0);
}
}
ci mod = 998244353;
ll fpow(ll a, ll x) {
ll res = 1;
while(x) {
if(x & 1) res = res * a % mod;
a = a * a % mod;
x >>= 1;
}
return res;
}
int dis[N];
void _dfs(int u, int la) {
dis[u] = dis[la] + 1;
for(pii e : A[u]) {
if(e.fi == la) continue;
_dfs(e.fi, u);
}
}
int main() {
// freopen("barrack.in", "r", stdin);
// freopen("barrack.out", "w", stdout);
freopen("a.in", "r", stdin);
rd(n, k);
rep(i, 2, n) {
int x, y, z;
rd(x, y, z);
A[x].eb(mp(y, z));
A[y].eb(mp(x, z));
}
int st = 1;
_dfs(1, 0);
rep(i, 2, n) {
if(dis[i] > dis[st]) {
st = i;
}
}
_dfs(st, 0);
rep(i, 1, n) {
if(dis[i] > dis[st]) {
st = i;
}
}
if(dis[st] < k) return puts("-1"), 0;
dfs1(1, 0);
dfs2(1, 0);
mx[1] = buc;
dfs(1, 0);
printf("%lld\n", ans % mod * fpow(n, mod - 2) % mod);
return 0;
}
T3 序列
标签
离线
线段树入门
思路
首先有 \(\gcd(x, x - v) = \gcd(x, x + v) = \gcd(x, v)\)
考虑将所有操作离线,对于每一个位置 \(i\) 处理询问。
第 \(j\) 次询问 \(p,k\) 相当于将 \(0\sim k - 1\) 的前缀和\(= a_i + \sum\limits_{q < k, i\in [l_q, r_q]} v_q\) 与 \(k\sim j\) 的 \(v\) 的 \(\gcd\) 求一个 \(\gcd\),开个线段树维护一下区间和和区间 \(\gcd\) 即可。
感觉比 T2 简单。
代码
代码好写。
code
ci N = 2.5e5 + 9;
int n, q;
int a0[N], qval[N], op[N];
ll ans[N];
vector<int> ins[N], ers[N];
vector<int> qry[N];
ll gcd(ll a, ll b) {return !b ? a : gcd(b, a % b);}
struct SGT {
#define lc ((u) << 1)
#define rc ((u) << 1 | 1)
int tr_gcd[N << 2];
ll tr_sum[N << 2];
void push_up(int u) {
tr_sum[u] = tr_sum[lc] + tr_sum[rc];
tr_gcd[u] = gcd(tr_gcd[lc], tr_gcd[rc]);
}
void modify(int u, int l, int r, int loc, int var) {
if(l == r) {
tr_gcd[u] = tr_sum[u] = var;
return;
}
int mid = (l + r) >> 1;
if(loc <= mid) modify(lc, l, mid, loc, var);
else modify(rc, mid + 1, r, loc, var);
push_up(u);
}
ll querysum(int u, int l, int r, int a, int b) {
if(a <= l && r <= b) return tr_sum[u];
if(b < l || r < a) return 0;
int mid = (l + r) >> 1;
return querysum(lc, l, mid, a, b) + querysum(rc, mid + 1, r, a, b);
}
int querygcd(int u, int l, int r, int a, int b) {
if(a <= l && r <= b) return tr_gcd[u];
if(b < l || r < a) return 0;
int mid = (l + r) >> 1;
return gcd(querygcd(lc, l, mid, a, b), querygcd(rc, mid + 1, r, a, b));
}
} tree;
int main() {
freopen("sequence.in", "r", stdin);
freopen("sequence.out", "w", stdout);
rd(n, q);
rep(i, 1, n) rd(a0[i]);
rep(i, 1, q) {
rd(op[i]);
if(op[i] == 1) {
int l, r; rd(l, r, qval[i]);
ins[l].eb(i);
ers[r + 1].eb(i);
}
else {
int p; rd(p, qval[i]);
qry[p].eb(i);
}
}
rep(i, 1, n) {
for(int j : ins[i]) {
tree.modify(1, 1, q, j, qval[j]);
}
for(int j : ers[i]) {
tree.modify(1, 1, q, j, 0);
}
for(int j : qry[i]) {
ans[j] = gcd(a0[i] + tree.querysum(1, 1, q, 1, qval[j] - 1), tree.querygcd(1, 1, q, qval[j], j));
}
}
rep(i, 1, q) {
if(op[i] == 2) {
printf("%lld\n", abs(ans[i]));
}
}
return 0;
}
2023/11/15 NOIP 模拟赛的更多相关文章
- 11/1 NOIP 模拟赛
11.1 NOIP 模拟赛 期望得分:50:实际得分:50: 思路:暴力枚举 + 快速幂 #include <algorithm> #include <cstring> #in ...
- 11.7 NOIP模拟赛
目录 2018.11.7 NOIP模拟 A 序列sequence(two pointers) B 锁lock(思路) C 正方形square(埃氏筛) 考试代码 B C 2018.11.7 NOIP模 ...
- 【2019.7.15 NOIP模拟赛 T2】与非树(nand)(树形DP)
树形\(DP\) 实际上,这道题应该不是很难. 我们设\(f_{x,i,j}\)表示在以\(x\)为根的子树内,原本应输出\(i\),结果输出了\(j\)的情况数. 转移时,为了方便,我们先考虑与,再 ...
- 【2019.7.15 NOIP模拟赛 T1】夹缝(mirror)(思维题)
思维题 此题应该是比较偏思维的. 假设一次反射后前进的距离是\(2^x(2y+1)\),则显然,它可以看做是前进距离为\(2^x\)的光线经过了\((2y+1)\)次反射,两者是等价的,甚至后者可能还 ...
- 2022.11.15 NOIP2022 模拟赛十
炸弹威力 Source:洛谷 P6036. 记 \(f_{i,0/1}\) 表示第 \(i\) 个位置为 \(0/1\) 的答案个数,有 DP 转移: \[\begin{aligned} (1-p_i ...
- NOIP模拟赛-2018.11.7
NOIP模拟赛 如果用命令行编译程序可以发现没加头文件之类的错误. 如果用命令行编译程序可以发现没加头文件之类的错误. 如果用命令行编译程序可以发现没加头文件之类的错误. 编译之前另存一份,听说如果敲 ...
- NOIP模拟赛-2018.11.6
NOIP模拟赛 今天想着反正高一高二都要考试,那么干脆跟着高二考吧,因为高二的比赛更有技术含量(我自己带的键盘放在这里). 今天考了一套英文题?发现阅读理解还是有一些困难的. T1:有$n$个点,$m ...
- NOIP模拟赛-2018.11.5
NOIP模拟赛 好像最近每天都会有模拟赛了.今天从高二逃考试跑到高一机房,然而高一也要考试,这回好像没有拒绝的理由了. 今天的模拟赛好像很有技术含量的感觉. T1:xgy断句. 好诡异的题目,首先给出 ...
- contesthunter暑假NOIP模拟赛第一场题解
contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...
- NOIP模拟赛 by hzwer
2015年10月04日NOIP模拟赛 by hzwer (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...
随机推荐
- 27 首页banner文库失效
安卓app 首页banner文库没有连接功能
- php页面调用微信扫一扫
function.php <?php define("appID", "微信公众号appId"); define("appsecret" ...
- MViTv2:Facebook出品,进一步优化的多尺度ViT | CVPR 2022
论文将Multiscale Vision Transformers (MViTv2) 作为图像和视频分类以及对象检测的统一架构进行研究,结合分解的相对位置编码和残差池化连接提出了MViT的改进版本 来 ...
- 洛谷P10693
洛谷P10693 好奇怪的题目编号 思路提取 input 11 2 13 4 5 3 7 9 9 11 11 12 output 9 以人造数据为例. 首先我们让\(i\)\(\to\)\(a_i\) ...
- 青少年CTF擂台挑战赛 2024 #Round 1
青少年CTF擂台挑战赛 2024 #Round 1 crypto 1.解个方程 题目: 欢迎来到青少年CTF,领取你的题目,进行解答吧!这是一道数学题!! p = 474356125652182661 ...
- 【Mybatis】Bonus01 笔记资料
对原生JDBC程序的问题总结 public void jdbc() { // 声明Connection对象 Connection con; // 驱动程序名 String driver = " ...
- 【Vue】15 VueX
[什么是VueX?] VueX是一个专门为Vue.js应用程序开发的状态管理模式, 采用集中式存储管理应用的所有组件状态, 以相应的规则保证按照一种可预测的方式发生改变. 即把多个组件的变量统一放到一 ...
- 【转载】 Sun RPC 编程简介
原文地址: http://blog.chinaunix.net/uid-1724205-id-2813082.html ======================================== ...
- 几乎纯css实现弹出框
今天需要做一个弹出框,右下角提示的那种 ,看了一两个jquery的插件 总是不太满意 .一方面js内容太多,另一方面 不太好配合已经存在的样式使用.所以 就自己用css直接实现了下 效果还可以 . 上 ...
- 最佳实践:解读GaussDB(DWS) 统计信息自动收集方案
摘要:现在商用优化器大多都是基于统计信息进行查询代价评估,因此统计信息是否实时且准确对查询影响很大,特别是分布式数据库场景.本文详细介绍GaussDB(DWS)如何实现了一种轻量.实时.准确的统计信息 ...