题目链接:

https://acm.hdu.edu.cn/contest/problem?cid=1072&pid=1005

题意:

给定大小为 n n n的可重集 A A A,给定非负整数 k , x k,x k,x。对于 A A A的一个非空子集 S S S,设 s u m ( S ) sum(S) sum(S)为集合 S S S的元素权值之和, ∣ S ∣ |S| ∣S∣为集合 S S S的元素个数。求 ∑ S ⊆ A , S ≠ ∅ s u m ( S ) k ⋅ x ∣ S ∣ \sum_{S\subseteq A,S \neq \varnothing}sum(S)^k \cdot x^{|S|} ∑S⊆A,S=∅​sum(S)k⋅x∣S∣对 998244353 998244353 998244353取模的结果。

算法:

NTT优化dp。

时间复杂度:

O ( n k l o g ( k ) ) O(nklog(k)) O(nklog(k))

解法:

为了便于理解,我们先设 d p i , j , l dp_{i,j,l} dpi,j,l​表示为前 i i i个,选 j j j个作为子集,在 l l l次幂下的答案。
设 p p p为前 i − 1 i-1 i−1个数中任选 j − 1 j-1 j−1个数的和, P P P为所有情况的 p p p的集合, P = { p 0 , p 1 , p 2 , . . . } P=\{p_0,p_1,p_2,...\} P={p0​,p1​,p2​,...}。

根据题意,可以得出前 i − 1 i-1 i−1个,选 j − 1 j-1 j−1个作为子集,在 l l l次幂下的答案 d p i − 1 , j − 1 , l = ( p 0 l + p 1 l + p 2 l + . . . ) x j − 1 dp_{i-1,j-1,l}=(p_0^l+p_1^l+p_2^l+...)x^{j-1} dpi−1,j−1,l​=(p0l​+p1l​+p2l​+...)xj−1。

设 s u m l = p 0 l + p 1 l + p 2 l + . . . sum_l=p_0^l+p_1^l+p_2^l+... suml​=p0l​+p1l​+p2l​+...,可得 d p i − 1 , j − 1 , l = s u m l x j − 1 dp_{i-1,j-1,l}=sum_l x^{j-1} dpi−1,j−1,l​=suml​xj−1。

考虑状态转移,考虑选 a i a_i ai​给答案带来的变化:

d p i , j , l = [ ( p 0 + a i ) l + ( p 1 + a i ) l + ( p 2 + a i ) l + . . . ] x j = [ ( l 0 ) a i l s u m 0 + ( l 1 ) a i l − 1 s u m 1 + ( l 2 ) a i l − 2 s u m 2 + . . . + ( l l ) a i 0 s u m l ] x j = [ ( l 0 ) a i l d p i − 1 , j − 1 , 0 + ( l 1 ) a i l − 1 d p i − 1 , j − 1 , 1 + ( l 2 ) a i l − 2 d p i − 1 , j − 1 , 2 + . . . + ( l l ) a i 0 d p i − 1 , j − 1 , l ] x = [ 1 0 ! ( l − 0 ) ! a i l d p i − 1 , j − 1 , 0 + 1 1 ! ( l − 1 ) ! a i l − 1 d p i − 1 , j − 1 , 1 + 1 2 ! ( l − 2 ) ! a i l − 2 d p i − 1 , j − 1 , 2 + . . . + 1 l ! ( l − l ) ! a i 0 d p i − 1 , j − 1 , l ] x l ! \begin{aligned} dp_{i,j,l}&=[(p_0+a_i)^l+(p_1+a_i)^l+(p_2+a_i)^l+...]x^j\\ &=[\binom{l}{0} a_i^l sum_0+\binom{l}{1} a_i^{l-1} sum_1+\binom{l}{2} a_i^{l-2} sum_2+...+\binom{l}{l} a_i^0 sum_l]x^j\\ &=[\binom{l}{0} a_i^l dp_{i-1,j-1,0}+\binom{l}{1} a_i^{l-1} dp_{i-1,j-1,1}+\binom{l}{2} a_i^{l-2} dp_{i-1,j-1,2}+...+\binom{l}{l} a_i^0 dp_{i-1,j-1,l}]x\\ &=[\frac{1}{0!(l-0)!} a_i^l dp_{i-1,j-1,0}+\frac{1}{1!(l-1)!} a_i^{l-1} dp_{i-1,j-1,1}+\frac{1}{2!(l-2)!} a_i^{l-2} dp_{i-1,j-1,2}+...+\frac{1}{l!(l-l)!} a_i^0 dp_{i-1,j-1,l}]x l! \end{aligned} dpi,j,l​​=[(p0​+ai​)l+(p1​+ai​)l+(p2​+ai​)l+...]xj=[(0l​)ail​sum0​+(1l​)ail−1​sum1​+(2l​)ail−2​sum2​+...+(ll​)ai0​suml​]xj=[(0l​)ail​dpi−1,j−1,0​+(1l​)ail−1​dpi−1,j−1,1​+(2l​)ail−2​dpi−1,j−1,2​+...+(ll​)ai0​dpi−1,j−1,l​]x=[0!(l−0)!1​ail​dpi−1,j−1,0​+1!(l−1)!1​ail−1​dpi−1,j−1,1​+2!(l−2)!1​ail−2​dpi−1,j−1,2​+...+l!(l−l)!1​ai0​dpi−1,j−1,l​]xl!​

我们发现化简到最后,参数 j j j并没有参与计算,因此可将式子转化为
d p i , l = [ 1 0 ! l ! a i l d p i − 1 , 0 + 1 1 ! ( l − 1 ) ! a i l − 1 d p i − 1 , 1 + 1 2 ! ( l − 2 ) ! a i l − 2 d p i − 1 , 2 + . . . + 1 l ! 0 ! a i 0 d p i − 1 , l ] x l ! dp_{i,l}=[\frac{1}{0!l!} a_i^l dp_{i-1,0}+\frac{1}{1!(l-1)!} a_i^{l-1} dp_{i-1,1}+\frac{1}{2!(l-2)!} a_i^{l-2} dp_{i-1,2}+...+\frac{1}{l!0!} a_i^0 dp_{i-1,l}]x l! dpi,l​=[0!l!1​ail​dpi−1,0​+1!(l−1)!1​ail−1​dpi−1,1​+2!(l−2)!1​ail−2​dpi−1,2​+...+l!0!1​ai0​dpi−1,l​]xl!

我们可以发现这就是个多项式乘法。

令 F ( u ) = 1 0 ! d p i − 1 , 0 u 0 + 1 1 ! d p i − 1 , 1 u 1 + 1 2 ! d p i − 1 , 2 u 2 + . . . + 1 l ! d p i − 1 , l u l F(u)=\frac{1}{0!} dp_{i-1,0}u^0+\frac{1}{1!} dp_{i-1,1}u^1+\frac{1}{2!} dp_{i-1,2}u^2+...+\frac{1}{l!} dp_{i-1,l}u^l F(u)=0!1​dpi−1,0​u0+1!1​dpi−1,1​u1+2!1​dpi−1,2​u2+...+l!1​dpi−1,l​ul,

G ( u ) = 1 0 ! a i 0 u 0 + 1 1 ! a i 1 u 1 + 1 2 ! a i 2 u 2 + . . . + 1 l ! a i l u l G(u)=\frac{1}{0!} a_i^0 u^0+\frac{1}{1!} a_i^1 u^1+\frac{1}{2!} a_i^2 u^2+...+\frac{1}{l!} a_i^l u^l G(u)=0!1​ai0​u0+1!1​ai1​u1+2!1​ai2​u2+...+l!1​ail​ul,

H ( u ) = F ( u ) G ( u ) x l ! H(u)=F(u)G(u)xl! H(u)=F(u)G(u)xl!。

那么 d p i , l = d p i − 1 , l + a i l x + [ u l ] H dp_{i,l}=dp_{i-1,l}+a_i^lx+[u^l]H dpi,l​=dpi−1,l​+ail​x+[ul]H( [ u l ] H [u^l]H [ul]H表示 H ( u ) H(u) H(u)的第 l l l项系数),最终答案为 d p n , k dp_{n,k} dpn,k​。

#include<bits/stdc++.h>
#define ll long long
#define L(i,j,k) for(ll i=(j);i<=(k);i++)
#define R(i,j,k) for(ll i=(j);i>=(k);i--)
#define inf 0x3f3f3f3f3f3f3f3f
#define vec vector
#define pll pair<ll,ll>
#define fi first
#define se second
#define pb push_back
#define mkp make_pair
#define MS(i,j,k) memset(i,j,sizeof(ll)*(k+2))
const ll N=1e5+10,M=10;
const ll mod=998244353,mmod=mod-1;
const double pi=acos(-1),eps=1e-8;
using namespace std;
ll fmul(ll a,ll b){a%=mod;b%=mod;ll res=0;while(b){if(b&1){res+=a;res%=mod;}a<<=1;if(a>=mod)a%=mod;b>>=1;}return res;}
ll gcd(ll x,ll y){if(y==0) return x;return gcd(y,x%y);}
ll fksm(ll a,ll b){ll r=1;if(b<0)b+=mod-1;for(a%=mod;b;b>>=1){if(b&1)r=r*a%mod;a=a*a%mod;}return r;}//a 分母; b MOD-2
ll lowbit(ll x){return x&(-x);}ll m,n,t,x,y,z,l,r,u,v,k,p,pp,nx,ny,nz,ansx,ansy,num,sum,mn,mx,ans;
ll lim,pos,tot,cnt,root,key,block;
ll a[N],dp[N];ll fac[N],fra[N],two=fksm(2,mod-2);
void init(ll n){//n阶阶乘初始化 fac[0]=1;L(i,1,n)fac[i]=fac[i-1]*i%mod;fra[n]=fksm(fac[n],mod-2);R(i,n-1,0)fra[i]=fra[i+1]*(i+1)%mod;
}
ll C(ll n,ll k){if(!n&&!k)return 1;if(n<k||k<0)return 0;return fac[n]*fra[k]%mod*fra[n-k]%mod;}//组合数ll R[N],a0[N],a1[N];
void init_ntt(ll limit){lim=1;ll k=0;while(lim<limit)lim*=2,k++;L(i,0,lim-1)R[i]=(R[i>>1]>>1)|((i&1)<<(k-1));}
void ntt(ll *f,ll type){ll G=3,Gi=fksm(G,mod-2);//mod=998244353,G=3;mod=1e9+7,G=5;L(i,0,lim-1)if(i<R[i])swap(f[i],f[R[i]]);for(ll mid=1;mid<lim;mid<<=1){ll Wn=fksm(type==1?G:Gi,(mod-1)/(mid<<1));for(ll j=0;j<lim;j+=(mid<<1)){ll w=1;for(ll k=0;k<mid;k++,w=(w*Wn)%mod){ll x=f[j+k],y=w*f[j+k+mid]%mod;f[j+k]=(x+y)%mod,f[j+k+mid]=(x-y+mod)%mod;}}}
}void NTT(ll *f,ll *g,ll siz0,ll siz1){init_ntt(siz0+siz1-1);L(i,siz0,lim)f[i]=0;L(i,siz1,lim)g[i]=0;ntt(f,1);ntt(g,1);L(i,0,lim-1)f[i]=(f[i]*g[i])%mod;ntt(f,-1);ll inv=fksm(lim,mod-2);L(i,0,lim-1)f[i]=f[i]*inv%mod;
}void solve(){scanf("%lld%lld%lld",&n,&k,&m);MS(dp,0,k);L(i,1,n)scanf("%lld",&a[i]);L(i,1,n){L(j,0,k){a0[j]=dp[j]*fra[j]%mod;a1[j]=fksm(a[i],j)*fra[j]%mod;}NTT(a0,a1,k+1,k+1);L(j,0,k)dp[j]=(dp[j]+fksm(a[i],j)*m%mod+a0[j]*m%mod*fac[j]%mod)%mod;}printf("%lld\n",dp[k]);
}int main(){// ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);// cout<<fixed<<setprecision(12);//精度init(10010);ll T=1;scanf("%lld",&T);while(T--)solve();
}

【2022 CCPC 华为云计算挑战赛】1005 带权子集和 (NTT 优化dp)相关推荐

  1. 洛谷P4072 [SDOI2016]征途(带权二分,斜率优化)

    洛谷题目传送门 一开始肯定要把题目要求的式子给写出来 我们知道方差的公式\(s^2=\frac{\sum\limits_{i=1}^{m}(x_i-\overline x)^2}{m}\) 题目要乘\ ...

  2. 2021-2022年度第三届全国大学生算法设计与编程挑战赛(秋季赛)- 分组(矩阵快速幂套NTT优化dp)

    题目链接:点击查看 题目大意:给出 nnn 个连续的小球,每次可以选择单独的一个或者相邻的两个小球分成一组,允许有剩余的小球,问恰好分成 k∈{1,2,3,⋯,m}k\in\{1,2,3,\cdots ...

  3. 2022年华为软件精英挑战赛区域初赛解读(基于数学规划模型附代码)

    0 写在前面的 本文是对2022年华为软件精英挑战赛(普朗克计划)区域初赛的一个解读.首先说明的是本文的算法无法直接拿来参赛的,因为区域初赛的要求是不能调用其它的算法包,python的话只能用nump ...

  4. 2022华为软件挑战赛流量管理

    1.题目描述 共有 M 个客户节点和 N 个边缘节点. 在每个时刻,要决策如何把每个客户节点的带宽需求分配到边缘节点. 为了确保调度质量,每个客户节点的需求只能分配到满足 QoS 约束的边缘节点 上. ...

  5. 2017华为软件挑战赛总结

    2017华为软件挑战赛总结 这次比赛是去年做的, 自己之前没有总结,现在才开始总结,很多东西快想不起来了,真是惭愧 赛题主要内容和目的 初赛题目和内容 给你一个流网络(边有容量和单位流量费用),已知有 ...

  6. 把云计算从云端带进国内的虚拟化软件

    本文讲的是把云计算从云端带进国内的虚拟化软件,云计算cloud computing是当前非常炙手可热的概念,它最早由1971年图灵奖得主John McCarthy于1961年提出.John McCar ...

  7. 人智化转型 华为云微认证带你实力进阶

    人智化转型 华为云微认证带你实力进阶 人智化转型不是一个伪命题或是一个超前的命题.这是一个实实在在正在发生的趋势,是所有已经完成云转型的大型科技企业的下一步.国内外的云计算企业已经对人工智能全力以赴, ...

  8. 【2022 CCPC 桂林站 日志】部分题解

    [2022 CCPC 桂林站] 蒟蒻侥幸铜(打铁原地退役算了 赛前看着参赛队伍大名单就感觉够呛,不少985/211等强校一队,rank+=n.实际战况确实如此,一边开题一边感慨这么多细节怎么这么多队直 ...

  9. 勇夺四冠,风行游艇在2022 CCPC专业站中展现超群实力

    8月28日,经过激烈角逐,为期三天的2022 CCPC中国量产车大赛专业站圆满落幕,在强敌环伺的赛事中,风行游艇脱颖而出,强势摘得四个比赛项目小组第一名,再次印证了卓越的产品实力. 征战2022 CC ...

最新文章

  1. java中Class.forName与new
  2. 编写一个函数,实现两个字符串的连接功能
  3. Android多媒体框架之MediaMetadataRetriever
  4. 最短路径dijkstra
  5. HBase在大搜车金融业务中的应用实践
  6. Hadoop的那些事儿
  7. 学python要有多少英语词汇量测试_“扫地僧”!自学Python编程、英语词汇量15000……北大保安再上热搜...
  8. java代码的运行顺序_java中的代码块执行顺序
  9. [Qt教程] 第33篇 网络(三)FTP(一)
  10. python加密反编译_对Python源码进行加密及反编译前后对比
  11. bzoj 1996: [Hnoi2010]chorus 合唱队
  12. 【免费毕设】ASP.NET电子购物商城系统(源代码+lunwen)
  13. 线程创建方式3-实现 callable接口(Java)
  14. NIOS II 常见问题总结FAQ - xiangyuqxq的专栏 - CSDN博客
  15. 反卷积可视化工具--deconv-deep-vis-toolbox
  16. SqlServer2008 数据库同步的两种方式(Sql JOB)
  17. 16进制颜色码对照表
  18. Python网络爬虫模块介绍:fake-useragent模块快速生成User-Agent信息
  19. Hexo中yilia主题使用问题总结
  20. vue 模拟随机变速的动态打字特效【支持多行文本】(含css实现闪烁光标,js动态改变setInterval定时器的时间间隔)

热门文章

  1. Android - 手机下载的缓存视频在文件管理怎么找不到?
  2. linux 复制 u盘 只读,Linux_ubuntu系统下向U盘拷贝数据提示目标是只读的,在ubuntu11.04下使用U盘的时候, - phpStudy...
  3. Linux apt-get 安装离线包
  4. jMetal学习笔记(二)-NSGAii源码解读
  5. Block.one的EOS区块链入门开发教程Elemental Battles
  6. android朋友圈发文字换行,微信朋友圈全文展开 朋友圈文字怎么换行朋友圈发多行文字...
  7. 计算机excel还原,3种方法找回电脑上已删除的Excel文档
  8. python常用的软件有哪些_Python编程常用软件有哪些?
  9. GEO-BYB型振弦式表面应变计的主要作用
  10. 浏览器劫持解决:解决浏览器的捆绑问题