bzoj 3027: [Ceoi2004]Sweet (生成函数)
题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=3027。
题目大意:有n种数,每种有Ci个,问你在这些数中取出[l,r]个,问你有多少种不同的取法,答案对2004取模。
数据范围:n≤10,Ci≤106,1≤l<r≤107。
我们不妨设f(n)表示不超过n的数的取法之和。
则答案显然为f(r)−f(l−1),下面来推导f(x)。
显然,f(m)等于多项式Πni=1∑Cij=1xi[0,m]的系数和。
考虑到Ci很大,如果直接多项式乘法,会T,必须化简。
原式
=Πni=11−xCi1−x。
=Πni=1(1−xCi)(1−x)n。
=Πni=1(1−xCi)∑∞j=−1(n+jn−1)x(j+1)
考虑式子的前半部分,不难发现,该部分最多只有2n个位置是非零的,显然我们只需要处理这部分,并不需要对整个多项式做乘法。实现该步骤一个dfs即可。
对于后半部分,假设求f(m)过程中前面通过dfs连乘出的单项式次数为k,系数为p,那么需要累加的答案显然多项式p×∑m−k−1j=−1(n+jn−1)x(j+1)。
然后根据组合数的相关公式进行化简,得到p×(n+m−k−1n−1)。
然后就愉快地昨晚啦
1 #include<bits/stdc++.h> 2 #define L long long 3 #define MOD 2004 4 using namespace std; 5 6 L n,a,b,now,ans=0; 7 L m[15]={0},mul=0; 8 9 L C(int n,int m){ 10 if(n<m) return 0; 11 L ans=1,mod=mul*MOD; 12 for(L i=n-m+1;i<=n;i++) 13 ans=i%mod*ans%mod; 14 return (ans/mul)%MOD; 15 } 16 17 void dfs(L dep,L fu,L mi,L lim){ 18 if(dep==n+1){ 19 now=(now+fu*C(n+lim-mi,n)%MOD)%MOD; 20 return; 21 } 22 dfs(dep+1,fu,mi,lim); 23 dfs(dep+1,-fu,mi+m[dep]+1,lim); 24 } 25 L calc(L hh){ 26 now=0; 27 dfs(1,1,0,hh); 28 return now; 29 } 30 int main(){ 31 cin>>n>>a>>b; 32 mul=1; for(int i=2;i<=n;i++) mul*=i; 33 for(int i=1;i<=n;i++) cin>>m[i]; 34 ans=((calc(b)-calc(a-1))%MOD+MOD)%MOD; 35 cout<<ans<<endl; 36 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!