zoukankan      html  css  js  c++  java
  • P4640[BJWC2008]王之财宝【OGF,Lucas定理】

    正题

    题目链接:https://www.luogu.com.cn/problem/P4640


    题目大意

    \(n\)种物品,其中\(t\)种物品是有个数限制的,第\(i\)种限制为\(b_i\),求选出\(m\)个物品的方案数\(\% p\)的值
    \(1\leq n,m,b_i\leq 10^9,0\leq t\leq 15,p\in[1,10^5]\cap Pri\)


    解题思路

    看上去就很\(\text{OGF}\)的题目?
    对于有限制的物品为\(f(x)=\frac{1-x^{b_i+1}}{1-x}\),其他都是\(f(x)=\frac{1}{1-x}\)

    然后\(n\)个乘起来的话然后求前\(m\)次项的系数。

    分子因为只有\(t\)个有值,直接暴力乘起来。下面那个分母是\(\frac{1}{(1-x)^n}\)

    所以对于上面如果有一个\(ax^{m-k}\)那么就会产生贡献

    \[a\sum_{i=0}^{k}\binom{n+i-1}{n}=a\binom{n+k}{n} \]

    (相等于选出\(0\sim k\)个球放进\(n\)个盒子里,开一个垃圾箱把没用的球放进去就好了)

    然后模数小,开\(Lucas\)就好了

    时间复杂度\(O(2^t\log_p n)\)


    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const ll N=1e5+10;
    ll n,t,m,p,b[20],ans,inv[N],fac[N];
    ll C(ll n,ll m)
    {return fac[n]*inv[m]%p*inv[n-m]%p;}
    ll L(ll n,ll m){
    	if(n<m)return 0;
    	if(n<p)return C(n,m);
    	return L(n/p,m/p)*L(n%p,m%p)%p;
    }
    signed main()
    {
    	scanf("%lld%lld%lld%lld",&n,&t,&m,&p);
    	for(ll i=0;i<t;i++)scanf("%lld",&b[i]),b[i]++;
    	inv[1]=1;
    	for(ll i=2;i<p;i++)
    		inv[i]=p-inv[p%i]*(p/i)%p;
    	inv[0]=fac[0]=1;
    	for(ll i=1;i<p;i++)
    		fac[i]=fac[i-1]*i%p,inv[i]=inv[i-1]*inv[i]%p;
    	ll MS=(1<<t); 
    	for(ll s=0;s<MS;s++){
    		ll f=1,sum=0;
    		for(ll i=0;i<t;i++)
    			if((s>>i)&1)f=-f,sum+=b[i];
    		(ans+=L(n+m-sum,n)*f)%=p;
    	}
    	printf("%lld\n",(ans+p)%p);
    	return 0;
    }
    
  • 相关阅读:
    使用java.util.Properties类读写配置文件
    maven配置文件setting.xml字段注释
    使用Nexus搭建Maven代理仓库
    Memcached 内存管理详解
    Memcached常用命令及使用说明
    使用NTP协议服务器时间同步
    Eclipse打JAR包的使用
    Eclipse插件的各种安装方法
    Java中代理对象的使用小结
    tp5框架成功、失败提示模板修改
  • 原文地址:https://www.cnblogs.com/QuantAsk/p/14599760.html
Copyright © 2011-2022 走看看