2026.2.27 NOI 模拟赛 题解
T1 #5541. 「2025 集训队互测 R2」第二基地
T2 LOJ #508. 「LibreOJ NOI Round #1」失控的未来交通工具
题意
\(n\) 点边带权无向图,加边,给定 \(u,v,a,b,c\) 查询有多少 \(0\le i<c\) 使得存在一条从 \(u\) 到 \(v\) 长度在 \(\bmod m\) 意义下与 \(a+ib\) 相同,\(n,q\le10^6\),\(m\le 10^9\)
分析
对于一个连通块钦定一点为根,则全体合法的长度为 \((i+kg)\bmod m\;(k\in \N)\),其中 \(g\) 为所有经过根的环的环长的 \(\gcd\),\(i\) 为 \(u,v\) 到根的距离之和
\(i\) 容易求出,得到 \(i,g\) 后容易通过 \(\text{exgcd}\) 求出答案,因此问题转化为维护每个连通块的 \(g\)
可证等价于以下过程:
边带权并查集维护连通性,令 \(d_u\) 表示 \(u\) 到根的距离,加入一条边 \((u,v,w)\) 时,若 \(u,v\) 不在同一连通块则合并两者并令新连通块的 \(g\) 为两个旧连通块的 \(g\) 的 \(\gcd\),否则将 \(w+d_u+d_v\) 加入当前连通块的 \(g\),两种情况都将 \(2w\) 并入 \(g\)
时间复杂度 \(O((n+q)(\alpha(n)+\log m))\)
T3 LOJ #510. 「LibreOJ NOI Round #1」北校门外的回忆
题意
优化以下代码:
#include <bits/stdc++.h>
using namespace std;
int n, q, k;
int lowbit(int x){
int m = 1;
while (x % k == 0)x /= k, m *= k;
return m * (x % k);
}
int main(){
cin >> n >> q >> k;
int a[n + 1]{};
while (q--){
int op, x, y;
cin >> op >> x;
if (op == 1){
for (cin >> y; x <= n; x += lowbit(x))a[x] ^= y;
} else {
for (y = 0; x; x -= lowbit(x))y ^= a[x];
cout << y << endl;
}
}
return 0;
}
其中 \(n\le 10^9\),\(k,q\le2\times10^5\),\(v\le10^9\)
分析
令 \(\text{lowbitv}(x)=\max_{p:p^k\mid x}p^k\),连边 \(x\to x+\text{lowbit}(x)\)(若 \(x+\text{lowbit}(x)>n\) 则忽略)
设 \(k=a\times 2^b\),其中 \(2\nmid a\),则对于 \(v\mid 0\le v<k,\frac v{2^b}\in \N\),\(v\gets v+\text{lowbit}(v)\) 的过程中,\(\text{lowbitv}(v)\) 不变,称这样的 \(v\) 为关键点
显然关键点的导出子图构成若干链(每个点至多一个前驱)
对于任意一个不在链上的点,显然至多走 \(O(\log n)\) 步就可以到链上,这 \(O(\log n)\) 步的贡献单独计算
对于每条链,用一颗线段树维护其贡献,显然为后缀异或和单点查询,因此问题转化为对于一个点找到所属链和在链上的位置
考虑在 \(\bmod k\) 意义下 \(x\to 2x\) 得到若干环,每一条链忽略对高位的进位就可以对应一个环
预处理环上走若干步到达的点和此过程中需要的进位即可
查询时只用到 \(O(\log_k n)\) 个单点查询,可以接受
时间复杂度 \(O(k\log k+q(\log^2n+\log_kn\log n))\)
比赛结果
\(0+100+75\),\(\text{rk}1\)

浙公网安备 33010602011771号