一、题目描述

  给定一个长度为 $n$ 的序列 $B$,和一个长度为 $n-1$ 的序列 $C$。

  保证 $b_i>=0$。令$S=\sum_{i=1}^n b_i$。

  一个长度为 $n$ 的且 $\sum_{i=1}^n a_i=S$ 序列 $A$ 的代价按照如下计算:

    你可以若干次任意选择一个 $i\in [1,n-1]$,然后选择下面两项之一:

    1、$a_i++,a_{i+1}--$

    2、$a_i--,a_{i+1}++$

    此操作的代价为 $c_i$

    $A$ 的代价即为把 $A$ 变成 $B$ 的最小代价。

  求出所有长度为 $n,a_i>=0$ 且 $\sum_{i=1}^na_i=S$ 的 $A$ 的代价和。答案对 $998244353$ 取模。

  数据范围:$1\le n\le 5\times  10^5,0\le S\le 2*10^6$。


 二、解题思路:

  令 $Sa_i=\sum_{k=1}^i a_k,Sb_i=\sum_{k=1}^i b_k$,于是可以比较简单地列出式子:

  $ans=\sum_{i=1}^{n-1}\sum_{Sa_i=0}^{V}\left|Sa_i-Sb_i\right|\times {Sa_i+i-1\choose i-1}{V+n-i-Sa_i-1\choose n-i-1}=ans_1+ans_2$

    $ans_1=\sum_{i=1}^{n-1}\sum_{Sa_i=0}^{Sb_i}(Sb_i-Sa_i)\times {Sa_i+i-1\choose i-1}{V+n-i-Sa_i-1\choose n-i-1}=\sum_{i=1}^{n-1}(B1_i-A1_i)$

      $B1_i=Sb_i\times \sum_{Sa_i=0}^{Sb_i}{Sa_i+i-1\choose i-1}{V+n-i-Sa_i-1\choose n-i-1}$

      $单独考虑式子G_{B1}(n,V,p,k)=\sum_{i=0}^{k}{i+p-1\choose p-1}{V+n-p-i-1\choose n-p-1}$

      $G_{B1}(n,V,p,k+1)=G_{B1}(n,V,p,k)+{k+p\choose p-1}{V+n-p-k-2\choose n-p-1}$

      $考虑组合意义,G_{B1}(n,V,p,k)表示前p个盒子小球总数小于等于k的方案数$

      $枚举j使得第(k+1)个小球放在j这个盒子里$

      $则G_{B1}(n,V,p,k)=\sum_{j=p+1}^n{k-1+j\choose j-1}{V-k-1+n-j\choose n-j}$

      $易得G_{B1}(n,V,p+1,k)=G_{B1}(n,V,p,k)-{k+p\choose p}{V-k-2+n-p\choose n-p-1}$

      $初始化k=0,p=1,G_{B1}(n,V,p,k)={V+n-2 \choose n-2}$

      $于是B1_i得到总复杂度O(n+V)的转移$

      $A1_i=\sum_{Sa_i=0}^{Sb_i}Sa_i\times {Sa_i+i-1\choose i-1}{V+n-i-Sa_i-1\choose n-i-1}$

        $=\sum_{Sa_i=0}^{Sb_i}Sa_i\times \frac{(Sa_i+i-1)!}{(i-1)!\times (Sa_i)!}{V+n-i-Sa_i-1\choose n-i-1}$

        $=\sum_{Sa_i=0}^{Sb_i}i\times \frac{(Sa_i+i-1)!}{i!\times (Sa_i-1)!}{V+n-i-Sa_i-1\choose n-i-1}$

        $=i\times \sum_{Sa_i=0}^{Sb_i}{Sa_i+i-1\choose i}{V+n-i-Sa_i-1\choose n-i-1}$

      $单独考虑式子G_{A1}(n,V,p,k)=\sum_{i=0}^{k}{i+p-1\choose i-1}{V+n-p-i-1\choose n-p-1}$

      $G_{A1}(n,V,p,k)=G_{B1}(n+1,V-1,p+1,k-1)$

      $G_{A1}(n,V,p,k+1)=G_{A1}(n,V,p,k)+{k+p\choose p}{V+n-p-k-2\choose n-p-1}$

      $G_{A1}(n,V,p+1,k)=G_{A1}(n,V,p,k)-{k+p\choose p+1}{V+n-p-k-2\choose n-p-1}$

      $初始化k=0,p=1,G_{A1}(n,V,p,k)=0$

      $于是A1_i得到总复杂度O(n+V)的转移$

    $于是可以O(n+V)求出ans1$

    $ans_2=\sum_{i=1}^{n-1}\sum_{Sa_i=Sb_i}^{V}(Sa_i-Sb_i)\times {Sa_i+i-1\choose i-1}{V+n-i-Sa_i-1\choose n-i-1}=\sum_{i=1}^{n-1}(A2_i-B2_i)$

      $B2_i=Sb_i\times \sum_{Sa_i=Sb_i}^V{Sa_i+i-1\choose i-1}{V+n-i-Sa_i-1\choose n-i-1}$

      $单独考虑式子G_{B2}(n,V,p,k)=\sum_{i=k}^V{i+p-1\choose p-1}{V+n-p-i-1\choose n-p-1}$

      $考虑组合意义,G_{B2}(n,V,p,k)表示前n-p个盒子小球总数小于等于V-k的方案数$

      $G_{B2}(n,V,p,k)=G_{B1}(n,V,n-p,V-k)$

      $G_{B2}(n,V,p,k+1)=G_{B2}(n,V,p,k)-{k+p-1\choose p-1}{V+n-p-k-1\choose n-p-1}$

      $G_{B2}(n,V,p+1,k)=G_{B2}(n,V,p,k)+{k+p-1\choose p}{V+n-p-k-1\choose n-p-1}$

      $初始化k=0,p=1,G_{B2}(n,V,p,k)={V+n-1\choose n-1}$

      $于是B2_i得到总复杂度O(n+V)的转移$

      $A2_i=\sum_{Sa_i=Sb_i}^VSa_i\times {Sa_i+i-1\choose i-1}{V+n-i-Sa_i-1\choose n-i-1}$

        $=\sum_{Sa_i=Sb_i}^VSa_i\times \frac{(Sa_i+i-1)!}{(i-1)!\times (Sa_i)!}{V+n-i-Sa_i-1\choose n-i-1}$

        $=\sum_{Sa_i=Sb_i}^Vi\times \frac{(Sa_i+i-1)!}{i!\times (Sa_i-1)!}{V+n-i-Sa_i-1\choose n-i-1}$

        $=i\times \sum_{Sa_i=Sb_i}^V{Sa_i+i-1\choose i}{V+n-i-Sa_i-1\choose n-i-1}$

      $单独考虑式子G_{A2}(n,V,p,k)=\sum_{i=k}^V{i+p-1\choose i-1}{V+n-p-i-1\choose n-p-1}$

      $G_{A2}(n,V,p,k)=G_{A1}(n,V,p,V)-G_{A1}(n,V,p,k-1)$

      $G_{A2}(n,V,p,k+1)=G_{A2}(n,V,p,k)-{k+p-1\choose k-1}{V+n-p-k-1\choose n-p-1}$

      $G_{A2}(n,V,p+1,k)=G_{A2}(n,V,p,k)+{k+p-1\choose p+1}{V+n-p-k-1\choose n-p-1}$

      $初始化k=0,p=1,G_{A2}(n,V,p,k)=\sum_{i=0}^Vi{V+n-i-2\choose n-2}$

      $这个初始化看得我很不爽,很想O(1)初始化,于是又推一下式子喽:$

      $原式=\sum_{i=0}^Vi{V+n-2-i\choose n-2}$

        $=\sum_{i=n-2-V}^{n-2}(n-2-i)\times{V+i\choose n-2}$

        $=\sum_{i=n-2-V}^{n-2}(n-2)\times{V+i\choose n-2}-\sum_{i=n-2}^{n-2+V}(i-V)\times{i\choose n-2}$

        $=V\times \sum_{i=0}^{V}{i+n-2\choose n-2}-(n-1)\times \sum_{i=0}^V{i+n-2\choose n-1}$

      $这一步运用上指标求和,即\sum_{i=0}^n{i\choose k}={n+1\choose k+1}。这也是我第一次运用上指标求和$

      $原式=V\times {V+n-1\choose V}-(n-1)\times {V+n-1\choose n}$

        $=n\times {V+n-1\choose n}-n\times {V+n-1\choose n}+{V+n-1\choose n}$

        $={V+n-1\choose n}$

      $于是A2_i得到总复杂度O(n+V)的转移$

    $于是可以O(n+V)求出ans2$

  $于是可以O(n+V)求出ans$

 

  式子推完了,说一下这题的几个关键点。

  1、一开始要敢大胆写式子,大胆拆式子。

  2、关于 $A1_i,A2_i$ 的转化应该是套路,学着点,把枚举的系数给他消了。

  3、$B1_i,B2_i$ 中考虑组合意义确实是神来之笔,多练练吧。

  4、式子可以写成函数的形式,然后可以往已经推出来的函数上面转化。感觉这题里的转化方式还不少。

  5、个人暂时水平较低,对于组合数中出现负数的情况尽量避免,调整好枚举的变量即可。


 三、完整代码

 1 #include<iostream>
 2 
 3 #define N 2500020
 4 #define lim 2500010
 5 #define ll long long
 6 #define mod 998244353 
 7 #define rep(i,l,r) for(ll i=l;i<=r;i++)
 8 #define per(i,r,l) for(int i=r;i>=l;i--)
 9 
10 using namespace std;
11 
12 ll n,ans,A,B,F,G,V;
13 ll p,k,a11,a12,a21,a22;
14 
15 ll fac[N],inv[N];
16 ll a[N],b[N],c[N]; 
17 
18 ll ksm(ll base,ll q){
19     ll res=1; while(q){
20         if(q&1) res*=base,res%=mod;
21         base*=base,base%=mod,q>>=1;
22     } return res;
23 }
24 void add(ll &u,ll v){
25     u+=v;
26     if(u>=mod) u-=mod;
27 }
28 ll C(ll n,ll m){
29     if(n<0||m<0||n<m) return 0;
30     return fac[n]*inv[m]%mod*inv[n-m]%mod;
31 }
32 
33 ll calc(ll x){
34     B=n-1;A=B+V-k;
35     if(p<x){
36         F=C(A-p-1,B-p),G=C(A-p,B-p);
37         add(a21,(C(k+p,p)*F+C(k+p-1,p)*G)%mod);
38         add(a22,(C(k+p,p+1)*F+C(k-1+p,p+1)*G)%mod);
39         p++;
40     }
41     
42     B=n-p-1;A=V+B;
43     while(k<b[x]){
44         F=C(A-k-1,B),G=C(A-k,B);
45         add(a12,(C(k+p,p)*F+C(k+p-1,p)*G)%mod);
46         add(a11,(C(k+p-1,k)*G+C(k+p,p-1)*F)%mod);
47         k++;
48     }
49     return ((mod+a11-a21)*b[x]+(mod+a22-a12)*x)%mod*c[x]%mod;
50 }
51 
52 void solve(){
53     cin>>n; ans=0;
54     
55     rep(i,1,n) cin>>b[i];
56     rep(i,1,n-1) cin>>c[i];
57     rep(i,1,n) b[i]+=b[i-1];
58     
59     V=b[n]; p=1,k=0,a11=0,a12=0;
60     a21=C(V+n-2,V-1),a22=C(V+n-1,n);
61     
62     rep(i,1,n-1) add(ans,calc(i));
63     cout<<ans<<'\n';
64 }
65 
66 signed main(){
67     ios::sync_with_stdio(false);
68     cin.tie(0); cout.tie(0);
69     
70     fac[0]=1; rep(i,1,lim) fac[i]=fac[i-1]*i%mod;
71     inv[lim]=ksm(fac[lim],mod-2); per(i,lim,1) inv[i-1]=inv[i]*i%mod;
72     
73     ll T; cin>>T;
74     rep(i,1,T) solve();
75     
76     return 0;
77 }

四、写题心得:

  好题,知识点不难,但题就是难,比较繁琐。

  喜欢 $feecle$ 选的题!拜谢。

  还是掌握了许多推式子的技巧,收获很大,但太耗时间了$qwq$

posted on 2024-02-05 10:45  trh0630  阅读(11)  评论(0编辑  收藏  举报