杂题 Part III

P14002

树的做法充分容易,考虑基环树,发现当前准备回溯是,由于在环上所以有 \(2\) 个被标为“在递归栈内”的结点。
我们任意访问一个,发现若周围有 \(2\) 个“在递归栈内”的结点,这个点一定不是父亲,不用动它,因为每次结点给出顺序相同,我们第一次找有第一个 \(2\),第二次找最后一个 \(2\)。否则发现我们不妨给这个点标记为 \(0\) 以区分。而我们来的时候给原来结点打一个新的标记,就可以知到我们现在在处于什么状态。
最后可能会有两个 \(2\) 均只有一个“在递归栈内”的结点与之相邻,画个图可以发现两个点必有一根,走哪边都是等价的。

AT_hitachi2020_f

考虑发掘性质:

  • 图的直径端点只有 \(2\) 个,否则可以把另一个直径端点操作成距离比原来小 \(1\) 的点,不影响直径长度。
  • 考虑刻画不能加边的性质,发现我们钦定一个点到直径中心(可能是一条边,这时不妨视为一个点,到两个端点的距离为 \(0.5\))的距离,发现距离相差不超过 \(1\) 的点之间可以连边,其余不能连边,于是问题转化为钦定距离大小。
  • 只有原树上的边会对距离差产生限制,容易树形 dp,状态记录当前子树中能作为直径端点的点有多少个,复杂度线性。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
inline ll Read() {
    int sig = 1; ll num = 0; char c = getchar();
    while(!isdigit(c)) { if(c == '-') sig = -1; c = getchar(); }
    while(isdigit(c)) num = (num << 3) + (num << 1) + (c ^ 48), c = getchar();
    return num * sig;
}
void Write(ll x) {
    if(x < 0) putchar('-'), x = -x;
    if(x > 9) Write(x / 10);
    putchar((x % 10) ^ 48);
}
const int N = 200005;
const ll Mod = 998244353, inv2 = (Mod + 1) / 2;
int n, dep[N], maxdep[N];
ll f[N][3][3], g[3][3];
vector<int> e[N];
void Dfs(int u, int fa) {
    maxdep[u] = dep[u] = dep[fa] + 1;
    for(auto v : e[u]) if(v != fa) Dfs(v, u), maxdep[u] = max(maxdep[u], maxdep[v]);
}
void Add(ll &x, ll y) { x += y; if(x >= Mod) x -= Mod; }
void Dfs2(int u, int fa, int dep) {
    if(!dep) f[u][1][1] = 1;
    else f[u][0][0] = 1;
    for(auto v : e[u]) if(v != fa) {
        int i, j, k, l, w; Dfs2(v, u, dep - 1), memset(g, 0, sizeof(g));
        for(i = 0; i < 3; i++) for(j = 0; j < 3; j++) for(k = 0; k < 3; k++) for(l = 0; l < 3; l++) {
            for(w = -1; w <= 1; w++) Add(g[w == 1 ? min(i + k, 2) : i][w == -1 ? min(j + l, 2) : j], f[u][i][j] * f[v][k][l] % Mod);
        }
        memcpy(f[u], g, sizeof(f[u]));
    }
}
int main() {
    int i, x, y, z; n = Read();
    for(i = 1; i < n; i++) { int u = Read(), v = Read(); e[u].emplace_back(v), e[v].emplace_back(u); }
    Dfs(1, 0); for(i = 1; i <= n; i++) if(dep[x] < dep[i]) x = i;
    Dfs(x, 0); for(i = 1; i <= n; i++) if(dep[x] < dep[i]) x = i;
    if(dep[x] & 1) {
        for(i = 1; i <= n; i++) if(dep[i] == (dep[x] + 1) / 2 && maxdep[i] == dep[x]) y = i;
        Dfs2(y, 0, dep[x] / 2), Write(f[y][1][1] * inv2 % Mod);
    }
    else {
        for(i = 1; i <= n; i++) {
            if(dep[i] == dep[x] / 2 && maxdep[i] == dep[x]) y = i;
            if(dep[i] == dep[x] / 2 + 1 && maxdep[i] == dep[x]) z = i;
        }
        Dfs2(y, z, dep[x] / 2 - 1), Dfs2(z, y, dep[x] / 2 - 1);
        Write((f[y][1][0] + f[y][1][1] + f[y][1][2]) * (f[z][1][0] + f[z][1][1] + f[z][1][2]) % Mod);
    }
}

CF1450H2

考虑刻画 \(f\),发现:

  • 最优情况下一定是贪心匹配相邻同色点。

证明:考虑调整。
图片
如图,D 区颜色全部相同,假设有形如黑边的白点的匹配,那么 \(A, B\) 之间的黑点匹配会有 \(2\) 的贡献,\(A/B, C\) 之间的黑点匹配会有 \(1\) 的贡献,然后调整为红边后,那么 \(A, B\) 之间的黑点匹配会有 \(0\) 的贡献,剩下的贡献不变,显然更优。

为了方便,我们令:\(a_{0/1}\) 表示偶数/奇数位置上的黑点个数,\(b_{0/1}\) 表示偶数/奇数位置上的白点个数,\(c_{0/1}\) 表示偶数/奇数位置上的问号个数,\(B = c_0 + c_1\)
单个问题答案是 \(\frac{|a_0 - a_1|}{2}\),有原问题答案:

\[\frac{1}{2^{B - 1}}\sum_{i = 0}^{c_0} \sum_{j = 0}^{c_1} [2 \mid (a_0 + i - a_1 - j)] \cdot \frac{|a_0 + i - a_1 - j|}{2} \cdot \binom{c_0}{i} \binom{c_1}{j} \]

即:

\[\frac{1}{2^B}\sum_{i = 0}^{c_0} \sum_{j = 0}^{c_1} [2 \mid (a_0 + i - a_1 - j)] \cdot |a_0 + i - a_1 - j| \cdot \binom{c_0}{i} \binom{c_1}{c_1 - j + i - i} \]

\(c_1 + i - j = x\),又有:

\[\frac{1}{2^B}\sum_{x = 0}^{c_0 + c_1} [2 \mid (a_0 - a_1 - c_1 + x)] \cdot |a_0 - a_1 - c_1 + x| \cdot \binom{c_0 + c_1}{x} \]

再令 \(A = -(a_0 - a_1 - c_1), B = c_0 + c_1\),有:

\[\frac{1}{2^B}\sum_{x = 0}^B [2 \mid (A - x)] \cdot |A - x| \cdot \binom{B}{x} \]

拆绝对值:

\[\frac{1}{2^B}[\sum_{x = 0}^A [2 \mid (A - x)] \cdot (A - x) \cdot \binom{B}{x} + \sum_{x = A + 2}^B [2 \mid (A - x)] \cdot (x - A) \cdot \binom{B}{x}] \]

后面那个太丑了:

\[\frac{1}{2^B}[2\sum_{x = 0}^A [2 \mid (A - x)] \cdot (A - x) \cdot \binom{B}{x} + \sum_{x = 0}^B [2 \mid (A - x)] \cdot (x - A) \cdot \binom{B}{x}] \]

进一步拆一下:

\[\begin{aligned} \frac{1}{2^B}[2\sum_{x = 0}^A [2 \mid (A - x)] \cdot A \cdot \binom{B}{x} - 2\sum_{x = 0}^A [2 \mid (A - x)] \cdot x \cdot \binom{B}{x} \\ + \sum_{x = 0}^B [2 \mid (A - x)] \cdot x \cdot \binom{B}{x} - \sum_{x = 0}^B [2 \mid (A - x)] \cdot A \cdot \binom{B}{x}] \end{aligned} \]

利用 \(\binom{a}{b}b = \binom{a - 1}{b - 1}a\)

\[\begin{aligned} \frac{1}{2^B}[2A\sum_{x = 0}^A [2 \mid (A - x)] \cdot \binom{B}{x} - 2B\sum_{x = 0}^{A - 1} [2 \mid (A - x - 1)] \cdot \binom{B - 1}{x} \\ + B\sum_{x = 0}^{B-1} [2 \mid (A - x - 1)] \cdot \binom{B - 1}{x - 1} - A\sum_{x = 0}^B [2 \mid (A - x)] \cdot \binom{B}{x}] \end{aligned} \]

这里对于 \(y \in \{0, 1\}\) 一定有:

\[F(P, Q - 1) = \sum_{x = 0}^P [x \bmod 2 = y] \cdot \binom{Q}{x} = \sum_{x = 0}^P \binom{Q - 1}{x} \]

所以先把原式变一下:

\[\begin{aligned} \frac{1}{2^B}[2A\cdot F(A, B - 1) - 2B\cdot F(A - 1, B - 2) + B2^{B - 2} - A2^{B - 1}] \end{aligned} \]

这里 \(A, B\) 的变化量是 \(O(1)\) 的,于是有:

\[\begin{aligned} F(P + 1, Q) = F(P, Q) + \binom{Q}{P + 1} \\ F(P, Q + 1) = 2F(P, Q) - \binom{Q}{P} \end{aligned}\]

可以做到 \(O(n + q)\),注意特判 \(B\) 很小的情况。

P14858

考虑 \((a + bi)(b + ai) = (a^2 + b^2)i\),于是我们特殊处理 \(ab \bmod p = 0\)\(a = b\) 的情况,剩下只需处理(令 \(t = \lfloor \frac{n}{p} \rfloor\)\(r = n \bmod p\)):

\[\prod_{i = 1}^{p - 1} \prod_{j = i + 1}^{p - 1} (i^2 + j^2)^{(t + [i \le r])(t + [j \le r])} \]

拆开乘方后均可以化成如下形式:

\[\prod_{i = 1}^A \prod_{j = i + 1}^B (i^2 + j^2) \]

\(k = i^2 + j^2\)

\[\prod_k k^{\sum_{i \le A \land i < j \le B} [i^2 + j^2 = k]} \]

可以使用 NTT,需要处理一下小于号的限制。

posted @ 2025-11-13 08:32  Include_Z_F_R_qwq  阅读(28)  评论(0)    收藏  举报