随笔 - 58,  文章 - 0,  评论 - 4,  阅读 - 3296

一、题目描述

  给定一个长度为 n 的序列 B,和一个长度为 n1 的序列 C

  保证 bi>=0。令S=i=1nbi

  一个长度为 n 的且 i=1nai=S 序列 A 的代价按照如下计算:

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

    1、ai++,ai+1

    2、ai,ai+1++

    此操作的代价为 ci

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

  求出所有长度为 n,ai>=0i=1nai=SA 的代价和。答案对 998244353 取模。

  数据范围:1n5×105,0S2106


 二、解题思路:

  令 Sai=k=1iak,Sbi=k=1ibk,于是可以比较简单地列出式子:

  ans=i=1n1Sai=0V|SaiSbi|×(Sai+i1i1)(V+niSai1ni1)=ans1+ans2

    ans1=i=1n1Sai=0Sbi(SbiSai)×(Sai+i1i1)(V+niSai1ni1)=i=1n1(B1iA1i)

      B1i=Sbi×Sai=0Sbi(Sai+i1i1)(V+niSai1ni1)

      GB1(n,V,p,k)=i=0k(i+p1p1)(V+npi1np1)

      GB1(n,V,p,k+1)=GB1(n,V,p,k)+(k+pp1)(V+npk2np1)

      GB1(n,V,p,k)pk

      j使(k+1)j

      GB1(n,V,p,k)=j=p+1n(k1+jj1)(Vk1+njnj)

      GB1(n,V,p+1,k)=GB1(n,V,p,k)(k+pp)(Vk2+npnp1)

      k=0,p=1,GB1(n,V,p,k)=(V+n2n2)

      B1iO(n+V)

      A1i=Sai=0SbiSai×(Sai+i1i1)(V+niSai1ni1)

        =Sai=0SbiSai×(Sai+i1)!(i1)!×(Sai)!(V+niSai1ni1)

        =Sai=0Sbii×(Sai+i1)!i!×(Sai1)!(V+niSai1ni1)

        =i×Sai=0Sbi(Sai+i1i)(V+niSai1ni1)

      GA1(n,V,p,k)=i=0k(i+p1i1)(V+npi1np1)

      GA1(n,V,p,k)=GB1(n+1,V1,p+1,k1)

      GA1(n,V,p,k+1)=GA1(n,V,p,k)+(k+pp)(V+npk2np1)

      GA1(n,V,p+1,k)=GA1(n,V,p,k)(k+pp+1)(V+npk2np1)

      k=0,p=1,GA1(n,V,p,k)=0

      A1iO(n+V)

    O(n+V)ans1

    ans2=i=1n1Sai=SbiV(SaiSbi)×(Sai+i1i1)(V+niSai1ni1)=i=1n1(A2iB2i)

      B2i=Sbi×Sai=SbiV(Sai+i1i1)(V+niSai1ni1)

      GB2(n,V,p,k)=i=kV(i+p1p1)(V+npi1np1)

      GB2(n,V,p,k)npVk

      GB2(n,V,p,k)=GB1(n,V,np,Vk)

      GB2(n,V,p,k+1)=GB2(n,V,p,k)(k+p1p1)(V+npk1np1)

      GB2(n,V,p+1,k)=GB2(n,V,p,k)+(k+p1p)(V+npk1np1)

      k=0,p=1,GB2(n,V,p,k)=(V+n1n1)

      B2iO(n+V)

      A2i=Sai=SbiVSai×(Sai+i1i1)(V+niSai1ni1)

        =Sai=SbiVSai×(Sai+i1)!(i1)!×(Sai)!(V+niSai1ni1)

        =Sai=SbiVi×(Sai+i1)!i!×(Sai1)!(V+niSai1ni1)

        =i×Sai=SbiV(Sai+i1i)(V+niSai1ni1)

      GA2(n,V,p,k)=i=kV(i+p1i1)(V+npi1np1)

      GA2(n,V,p,k)=GA1(n,V,p,V)GA1(n,V,p,k1)

      GA2(n,V,p,k+1)=GA2(n,V,p,k)(k+p1k1)(V+npk1np1)

      GA2(n,V,p+1,k)=GA2(n,V,p,k)+(k+p1p+1)(V+npk1np1)

      k=0,p=1,GA2(n,V,p,k)=i=0Vi(V+ni2n2)

      O(1)

      =i=0Vi(V+n2in2)

        =i=n2Vn2(n2i)×(V+in2)

        =i=n2Vn2(n2)×(V+in2)i=n2n2+V(iV)×(in2)

        =V×i=0V(i+n2n2)(n1)×i=0V(i+n2n1)

      i=0n(ik)=(n+1k+1)

      =V×(V+n1V)(n1)×(V+n1n)

        =n×(V+n1n)n×(V+n1n)+(V+n1n)

        =(V+n1n)

      A2iO(n+V)

    O(n+V)ans2

  O(n+V)ans

 

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

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

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

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

  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   trh0630  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示