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\)

posted @ 2026-02-28 18:17  Hstry  阅读(0)  评论(0)    收藏  举报