zoukankan      html  css  js  c++  java
  • 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
    ",ans);
      return 0;
    }
    
    
  • 相关阅读:
    (转载)链表环中的入口点 编程之美 leecode 学习
    leecode single numer
    leecode 树的平衡判定 java
    Let the Balloon Rise
    Digital Roots
    大数加法,A+B
    小希的迷宫
    畅通工程
    lintcode596- Minimum Subtree- easy
    lintcode597- Subtree with Maximum Average- easy
  • 原文地址:https://www.cnblogs.com/Yuzao/p/8454573.html
Copyright © 2011-2022 走看看