HNOI2008 Cards
ovo这其实是一道置换 + DP的题,不过蒟蒻已经快忘了置换怎么做了……
或许这道题使用组合数的方法更容易一些。
我们先考虑一下,满足题目中各种卡牌颜色要求的染色个数一共有多少种,这个很显然,是C(n,sr)* C(n - sr,sb) * C(n-sr-sb,sg)(后面那项结果就是1其实)
之后,题目中提到,保证任意多次洗牌都可用这 m种洗牌法中的一种代替,且对每种洗牌法,都存在一种洗牌法使得能回到原状态。
也就是说,对于一种状态A,有另外m中状态能够由它变来(自然也能由这些状态变回A),而其他的状态则不能从A变来。因为任意多次洗牌都可以用m种之一替代,所以肯定是可以从A这种状态再变出来m种的。
而我们再考虑,如果A能够变成一种状态B,它不属于这m+1种状态之一,但是根据题目描述,它一定是可以变回A,转变成了A,就可以转换为其他状态,这与它原来不在这m+1中状态中是矛盾的。
所以,在这些染色方法中,每m+1中染色方式是被绑定在一起的,是本质相同的,所以计算出来染色总数除以(m+1)即为结果。
先处理出来阶乘和阶乘的逆元就可以了。
#include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #define rep(i,a,n) for(ll i = a;i <= n;i++) #define per(i,n,a) for(ll i = n;i >= a;i--) #define enter putchar('\n') using namespace std; const int M = 105; typedef long long ll; ll read() { ll ans = 0,op = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') op = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { ans *= 10; ans += ch - '0'; ch = getchar(); } return ans * op; } ll qpow(ll a,ll b,ll mod) { ll q = 1; while(b) { if(b&1) q *= a,q %= mod; a *= a,a %= mod; b >>= 1; } return q % mod; } ll m,n,inv[M],sum[M],p,sr,sb,sg; ll C(ll a,ll b) { return sum[a] * inv[b] * inv[a-b] % p; } int main() { inv[0] = 1,sum[0] = 1,inv[1] = 1; sr = read(),sb = read(),sg = read(),m = read(),p = read(); n = sr+sb+sg; rep(i,1,p-1) sum[i] = sum[i-1] * i % p; inv[p-1] = qpow(sum[p-1],p-2,p); per(i,p-1,2) inv[i-1] = inv[i] * i % p; printf("%lld\n",C(n,sr) * C(n-sr,sb) * qpow(m+1,p-2,p) % p); return 0; }
当你意识到,每个上一秒都成为永恒。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现