• Solution 「LNOI 2022」「洛谷 P8367」盒


    \(\mathscr{Desription}\)

      Link.

      有 \(n\) 个盒子排成一排,第 \(i\) 个盒子内有 \(a_i\) 个球。球可以在相邻盒子间传递,\(i\)\(i+1\) 间的单位传递费用是 \(w_i\)。对于所有 \(\{b_{1..n}\}\in\mathbb{N}^n,\sum_{i=1}^nb_i=\sum_{i=1}^na_i:=S\),求通过传递使得 \(a=b\) 的最小费用和。答案模 \(998244353\)

      \(n\le5\times10^5\)\(S\le2\times10^6\)

    \(\mathscr{Solution}\)

      答案显然是

    \[\textit{ans}=\sum_{i=1}^{n-1}w_i\sum_{j=0}^S|j-s_i|\binom{i+j-1}{j}\binom{S-j+n-i-1}{S-j}. \]

    这个 \(w_i\) 的高情商理解当然是:我们需要求出每个

    \[\begin{aligned} r_i&=\sum_{j=0}^S|j-s_i|\binom{i+j-1}{j}\binom{S-j+n-i-1}{S-j}\\ &=2\sum_{j=0}^{s_i}(s_i-j)\binom{i+j-1}{j}\binom{S-j+n-i-1}{S-j}\\ &~~~~+\sum_{j=0}^S(j-s_i)\binom{i+j-1}{j}\binom{S-j+n-i-1}{S-j}. \end{aligned} \]

    注意第二步的绝对值拆得比较有心机,保持求和指标从 \(0\) 开始,使得式子的组合意义更优美。

      两项分别算叭。设 \(r_i=p_i+q_i\)。首先利用恒等式 \(j\binom{i+j-1}{j}=i\binom{i+j-1}{j-1}\) 化简 \(p,q\),此后观察到 \(q_i\) 的求和是对组合数所有有意义的上指标求和,它应该比较好化简。浅推一下:

    \[\begin{aligned} q_i&=i\sum_{j=0}^{S-1}\binom{i+j}{j}\binom{S-j+n-i-2}{S-j-1}-s_i\sum_{j=0}^S\binom{i+j-1}{j}\binom{S-j+n-i-1}{S-j}\\ &=i\sum_{j=0}^{S-1}\binom{i+j}{i}\binom{S-j+n-i-2}{n-i-1}-\cdots\\ &=i\binom{i+1+S+n-i-2}{i+1+n-i-1}-\cdots\quad\quad(*)\\ &=i\binom{S+n-1}{n}-s_i\sum_{j=0}^S\binom{i+j-1}{i-1}\binom{S-j+n-i-1}{n-i-1}\\ &=\cdots-s_i\binom{i-1+1+S+n-i-1}{i-1+1+n-i-1}\\ &=i\binom{S+n-1}{n}-s_i\binom{S+n-1}{n-1}. \end{aligned} \]

    其中 \((*)\) 是经典组合意义:在 \(S+n-1\) 个球中选 \(n\) 个,其中第 \(i+1\) 个钦定为分隔球,就得到了原乘积式的组合方案。

      接下来解决 \(p\)。先做类似 \(q\) 的前两步化简,然后细看一下,把两个和式单独考虑:

    \[\frac{1}{2}p_i=-if(i,s_i-1)+s_ig(i,s_i). \]

      类似于 \((*)\)\(f(x,y)\) 的组合意义为:在 \(S+n-1\) 个球里选 \(n\) 个,要求选的第 \(x+1\) 个球的位置不超过 \(x+y+1\)\(g(x,y)\) 的组合意义为:在 \(S+n-1\) 个球里选 \(n-1\) 个,要求选的第 \(x\) 个球的位置不超过 \(x+y\)。敏锐地注意到:\(f,g\) 都可以利用 \((x,y)\) 的一个前驱状态添加或减少边界情况的方案得到。另一方面,原式恰好满足 \(x,y\) 分别不递减。因此,我们可以维护 \(f(x,y)\)\(g(x,y)\),将 \((x,y)\) 随着和式做指针移动。具体地,通过组合意义的理解,不难得到:

    \[f(x,y)=\binom{x+y}{x}\binom{S+n-2-x-y}{n-1-x}+f(x,y-1),\\ f(x,y)=f(x-1,y)-\binom{x+y}{x}\binom{S+n-2-x-y}{n-x};\\ g(x,y)=\binom{x+y-1}{x-1}\binom{S+n-1-x-y}{n-1-x}+g(x,y-1),\\ g(x,y)=g(x-1,y)-\binom{x+y-1}{x-1}\binom{S+n-1-x-y}{n-x}. \]

    可见,\((x,y)\) 移动到 \((x+1,y)\) 或者 \((x,y+1)\) 都是 \(\mathcal O(1)\) 的,均摊下来,我们就能 \(\mathcal O(n+S)\) 求出 \(f,g\)。所以总复杂度就是 \(\mathcal O(T(n+S))\)

    \(\mathscr{Code}\)

    /*+Rainybunny+*/
    
    #include <bits/stdc++.h>
    
    #define rep(i, l, r) for (int i = l, rep##i = r; i <= rep##i; ++i)
    #define per(i, r, l) for (int i = r, per##i = l; i >= per##i; --i)
    
    inline char fgc() {
        static char buf[1 << 17], *p = buf, *q = buf;
        return p == q && (q = buf + fread(p = buf, 1, 1 << 17, stdin), p == q) ?
          EOF : *p++;
    }
    
    template <typename Tp = int>
    inline Tp rint() {
        Tp x = 0, s = fgc(), f = 1;
        for (; s < '0' || '9' < s; s = fgc()) f = s == '-' ? -f : f;
        for (; '0' <= s && s <= '9'; s = fgc()) x = x * 10 + (s ^ '0');
        return x * f;
    }
    
    template <typename Tp>
    inline void wint(Tp x) {
        if (x < 0) putchar('-'), x = -x;
        if (9 < x) wint(x / 10);
        putchar(x % 10 ^ '0');
    }
    
    const int MAXN = 5e5, MAXS = 2e6, MOD = 998244353;
    int n, a[MAXN + 5], w[MAXN + 5], fac[MAXN + MAXS + 5], ifac[MAXN + MAXS + 5];
    
    inline int mul(const int u, const int v) { return 1ll * u * v % MOD; }
    inline void subeq(int& u, const int v) { (u -= v) < 0 && (u += MOD); }
    inline int sub(int u, const int v) { return (u -= v) < 0 ? u + MOD : u; }
    inline void addeq(int& u, const int v) { (u += v) >= MOD && (u -= MOD); }
    inline int add(int u, const int v) { return (u += v) < MOD ? u : u - MOD; }
    inline int mpow(int u, int v) {
        int ret = 1;
        for (; v; u = mul(u, u), v >>= 1) ret = mul(ret, v & 1 ? u : 1);
        return ret;
    }
    
    inline void init(const int s) {
        fac[0] = 1;
        rep (i, 1, s) fac[i] = mul(i, fac[i - 1]);
        ifac[s] = mpow(fac[s], MOD - 2);
        per (i, s - 1, 0) ifac[i] = mul(i + 1, ifac[i + 1]);
    }
    
    inline int bino(const int u, const int v) {
        return v < 0 || u < v ? 0 : mul(fac[u], mul(ifac[v], ifac[u - v]));
    }
    
    int main() {
        init(MAXN + MAXS);
        for (int T = rint(); T--;) {
            n = rint();
            rep (i, 1, n) a[i] = a[i - 1] + rint();
            rep (i, 1, n - 1) w[i] = rint();
    
            int ans = 0, S = a[n];
            int fx = 0, fy = 0, fv = bino(S + n - 2, n - 1);
            int gx = 1, gy = 0, gv = bino(S + n - 2, n - 2);
            rep (i, 1, n - 1) {
                addeq(ans, mul(w[i], sub(mul(i, bino(S + n - 1, n)),
                  mul(a[i], bino(S + n - 1, n - 1)))));
                while (fx < i) {
                    ++fx;
                    subeq(fv, mul(bino(fx + fy, fx),
                      bino(S + n - 2 - fx - fy, n - fx)));
                }
                while (fy < a[i] - 1) {
                    ++fy;
                    addeq(fv, mul(bino(fx + fy, fx),
                      bino(S + n - 2 - fx - fy, n - 1 - fx)));
                }
                while (gx < i) {
                    ++gx;
                    subeq(gv, mul(bino(gx + gy - 1, gx - 1),
                      bino(S + n - 1 - gx - gy, n - gx)));
                }
                while (gy < a[i]) {
                    ++gy;
                    addeq(gv, mul(bino(gx + gy - 1, gx - 1),
                      bino(S + n - 1 - gx - gy, n - 1 - gx)));
                }
                addeq(ans, mul(mul(2, w[i]),
                  sub(mul(a[i], gv), mul(i, fy == a[i] - 1 ? fv : 0))));
            }
            wint(ans), putchar('\n');
        }
        return 0;
    }
    
    
  • 相关阅读:
    RayTracing练习
    聚类方法总结
    Mysql、SqlServer和Oracle 添加修改删除字段
    gridview增加thead 和tbody
    数据库设计的三大范式
    c#+sql事务
    gridview应用
    DOS命令大全 IIS命令大全 SQL命令大全……
    TFS
    C#.NET官方类库Json序列化,反序列化
  • 原文地址:https://www.cnblogs.com/rainybunny/p/16353143.html
Copyright © 2020-2023  润新知