【CF660E】Different Subsets For All Tuples(组合数学)
分类:
CodeForces
大致题意: 有一个长度为的数列,每个位置上数字的值在范围内,则共有种可能的数列。分别求出每个数列中本质不同的子序列个数,然后求和。
一些分析
首先,我们单独考虑空序列的个数,然后接下来就可以只考虑非空序列的个数了。
假设有一个长度为的子序列(),且其在序列中的位置分别为,值分别为。
则我们强制在范围内不能出现,范围内不能出现,以此类推。
所以,在前个位置中,除这个位置填外,如上所述,其余个位置各有种填法。
而在第个位置之后就可以随便填了,每个位置都有种填法。
推式子
通过之前的分析,于是得到式子如下:
对于这个式子的解释:
首先,用枚举子序列长度,而长度为的子序列共有种可能。
接下来枚举,而依次选择(即这里的)这个范围内的任意位置都是合法的,就相当于在个位置中选择个位置,方案数就是。
从前文可得,(即这里的)个位置有种填法,(即这里的)个位置有种填法。
于是便得到上述式子。
然后就是化简:
先移项,把移进去得到:
改变枚举顺序,得到:
观察到组合数中的和,不难想到直接将枚举的减,即:
然后我们可以化简一下系数,发现这些和恰好抵消了,得到:
然后我们拎出,就可以得到:
那这样有什么好处呢?
回想一下二项式定理:。
这似乎与上面式子的后半部分有几分相似。
于是就可以化简得到:
这个式子可以快速幂计算,也可以直接计算。
总而言之,可以过了。
代码
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 1000000
#define X 1000000007
#define Qinv(x) Qpow(x,X-2)
#define Inc(x,y) ((x+=(y))>=X&&(x-=X))
using namespace std;
int n,m;
I int Qpow(RI x,RI y) {RI t=1;W(y) y&1&&(t=1LL*t*x%X),x=1LL*x*x%X,y>>=1;return t;}//快速幂
int main()
{
RI i,ans,p1,p2,b1,b2;
scanf("%d%d",&n,&m),ans=p1=Qpow(m,n),p2=1,b1=Qinv(m),b2=(1LL*2*m-1)%X;//初始化
for(i=0;i^n;++i) Inc(ans,1LL*p1*p2%X),p1=1LL*p1*b1%X,p2=1LL*p2*b2%X;//O(n)计算答案
return printf("%d",ans),0;//输出答案
}
待到再迷茫时回头望,所有脚印会发出光芒
分类:
CodeForces
标签:
组合数学
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· Apache Tomcat RCE漏洞复现(CVE-2025-24813)