• AT4119[ARC096C]Everything on It【斯特林数,容斥】


    正题

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


    题目大意

    一个集合\(S=\{k\in[1,n]\cup N\}\),它的所有子集作为元素组成的集合中要求满足每一个数字的出现之和不小于\(2\),求方案数对\(P\)取模。

    \(1\leq n\leq 3000,P\in[10^8,10^{9}+9]\cup Pri\)


    解题思路

    考虑至少\(i\)个数选择次数不超过\(1\),那么这个方案的容斥系数就是\((-1)^i\)

    考虑怎么求这个方案,我们可以先不要被限制了的数,然后再将这些被限制了的数丢进被选出了的集合中。设有\(j\)个集合包含被限制了的数,那么丢进这些集合的方案就是\(\begin{Bmatrix} i+1\\j+1 \end{Bmatrix}\)(一个数字可以选择不丢所以开一个新的集合表示这个集合内的数不使用),然后剩下的数随意的选入这些集合中就是\((2^{n-i})^j\)
    那么答案出来了

    \[\sum_{i=0}^n(-1)^i2^{2^{n-i}}\binom{n}{i}\sum_{j=0}^i\begin{Bmatrix}i+1\\ j+1\end{Bmatrix}(2^{n-i})^j \]

    直接预处理斯特林数计算就好了,时间复杂度\(O(n^2)\)


    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const ll N=3100;
    ll n,P,s[N][N],fac[N],ans;
    ll power(ll x,ll b,ll p=P){
    	ll ans=1;
    	while(b){
    		if(b&1)ans=ans*x%p;
    		x=x*x%p;b>>=1;
    	}
    	return ans;
    }
    ll C(ll n,ll m)
    {return fac[n]*power(fac[m],P-2)%P*power(fac[n-m],P-2)%P;}
    signed main()
    {
    	scanf("%lld%lld",&n,&P);s[0][0]=fac[0]=1;
    	for(ll i=1;i<=n;i++)fac[i]=fac[i-1]*i%P;
    	for(ll i=1;i<=n+1;i++)
    		for(ll j=1;j<=i;j++)
    			s[i][j]=(s[i-1][j-1]+j*s[i-1][j]%P)%P;
    	for(ll i=0;i<=n;i++){
    		ll sum=0,tmp=power(2,power(2,n-i,P-1));
    		if(i&1)tmp=P-tmp;tmp=tmp*C(n,i)%P;
     		for(ll j=0,z=1,p=power(2,n-i);j<=i;j++,z=z*p%P)
    			(sum+=s[i+1][j+1]*z%P)%=P;
    		(ans+=sum*tmp)%=P;
    	}
    	printf("%lld\n",ans);
    	return 0;
    }
    
  • 相关阅读:
    复位电路
    Tcl与Design Compiler (十三)——Design Compliler中常用到的命令(示例)总结
    Python Twisted系列教程1:Twisted理论基础
    Python Twisted架构英文版
    Python Twisted网络编程框架与异步编程入门教程
    windows下安装Python虚拟环境virtualenvwrapper-win
    数据库事务解析
    Python之select模块解析
    windows右键打开方式里面添加新的应用程序
    HTTP协议的状态码
  • 原文地址:https://www.cnblogs.com/QuantAsk/p/14463749.html
Copyright © 2020-2023  润新知