bzoj 1272: [BeiJingWc2008]Gate Of Babylon

Posted Boss.Pi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 1272: [BeiJingWc2008]Gate Of Babylon相关的知识,希望对你有一定的参考价值。

Description

技术分享图片
技术分享图片

Solution

如果没有限制,答案就是 \(\sum_{i=0}^{m}C(n+i-1,i)\)
表示枚举每一次取的个数,且不超过 \(m\),方案数为可重组合
发现这个东西可以用杨辉三角合并,最终变成 \(C(n+m,m)\)

考虑有限制的情况,直接容斥一下即可,要使得一种物品不合法,我们先强制给他选 \(B_i+1\) 个,剩下的随意选
此题求组合数需要用 \(Lucas\)

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,T,m,mod,a[20],ans=0,Fac[N],inv[N];
inline int C(int a,int b){
    if(a<b)return 0;
    return 1ll*Fac[a]*inv[b]*inv[a-b]%mod;
}
inline int lucas(int a,int b){
    if(a<0 || b<0 || a<b)return 0;
    if(a<mod && b<mod)return C(a,b);
    return 1ll*lucas(a/mod,b/mod)*C(a%mod,b%mod)%mod;
}
inline void dfs(int x,int o,int t){
    if(x==T+1){
        ans=(ans+o*lucas(n+m-t,m-t))%mod;
        return ;
    }
    dfs(x+1,-o,t+a[x]+1);
    dfs(x+1,o,t);
}
int main(){
  freopen("pp.in","r",stdin);
  freopen("pp.out","w",stdout);
  scanf("%d%d%d%d",&n,&T,&m,&mod);
  inv[0]=inv[1]=Fac[0]=Fac[1]=1;
  for(int i=2;i<=mod;i++){
      Fac[i]=1ll*Fac[i-1]*i%mod;
      inv[i]=(-1ll*(mod/i)*inv[mod%i]%mod+mod)%mod;
  }
  for(int i=2;i<=mod;i++)inv[i]=1ll*inv[i-1]*inv[i]%mod;
  for(int i=1;i<=T;i++)scanf("%d",&a[i]);
  dfs(1,1,0);
  if(ans<0)ans+=mod;
  printf("%d\n",ans);
  return 0;
}

以上是关于bzoj 1272: [BeiJingWc2008]Gate Of Babylon的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 1270 BeijingWc2008 雷涛的小猫

BZOJ1270: [BeijingWc2008]雷涛的小猫

bzoj1270 [BeijingWc2008]雷涛的小猫

bzoj 1270 [BeijingWc2008]雷涛的小猫

bzoj1270[BeijingWc2008]雷涛的小猫 dp

BeijingWc 2008 秦腾与教学评估