• Topcoder CyclesNumber 和 ARC96E Everything on It


    CyclesNumber

    求所有 (n) 个点的置换的轮换个数 (m) 次⽅的和。

    (Tleq 300,n leq 10^5,mleq 300)

    题解

    https://www.cnblogs.com/jefflyy/p/9425348.html

    前置知识

    根据《具体数学》,斯特林数有性质:

    [egin{Bmatrix}n+1\m+1end{Bmatrix}=sum_{k=m}^ninom{n}{k}egin{Bmatrix}k\mend{Bmatrix}\ egin{bmatrix}n+1\m+1end{bmatrix}=sum_{k=m}^ninom{n}{k}egin{bmatrix}k\mend{bmatrix}(n-k)!=n!sum_{k=m}^nfrac{egin{bmatrix}k\mend{bmatrix}}{k!}\ ]

    这两个公式的组合意义很显然,并且应该可以用归纳法证明。

    还有一个类似的式子:

    [egin{bmatrix}n+1\m+1end{bmatrix}=sum_{k=m}^negin{bmatrix}n\kend{bmatrix}inom{k}{m} ]

    但它并没有什么组合意义,尝试用归纳法证明它。

    [egin{bmatrix}n+1\m+1end{bmatrix}=egin{bmatrix}n\mend{bmatrix}+negin{bmatrix}n\m+1end{bmatrix}\ egin{bmatrix}n\mend{bmatrix}=sum_{k=m-1}^{n-1}egin{bmatrix}n-1\kend{bmatrix}inom{k}{m-1}\ negin{bmatrix}n\m+1end{bmatrix}=nsum_{k=m}^{n-1}egin{bmatrix}n-1\kend{bmatrix}inom{k}{m}\ ]

    注意到组合数的第二维不同,因此首要任务是把组合数拼起来。

    [egin{bmatrix}n\mend{bmatrix}=sum_{k=m}^{n}egin{bmatrix}n-1\k-1end{bmatrix}inom{k-1}{m-1}\ negin{bmatrix}n\m+1end{bmatrix}=sum_{k=m+1}^{n}egin{bmatrix}n-1\k-1end{bmatrix}inom{k-1}{m}+(n-1)sum_{k=m}^{n-1}egin{bmatrix}n-1\kend{bmatrix}inom{k}{m}\ egin{bmatrix}n\mend{bmatrix}+negin{bmatrix}n\m+1end{bmatrix}=sum_{k=m}^negin{bmatrix}n-1\k-1end{bmatrix}left(inom{k-1}{m-1}+inom{k-1}{m} ight)+(n-1)sum_{k=m}^{n-1}egin{bmatrix}n-1\kend{bmatrix}inom{k}{m}\ =sum_{k=m}^negin{bmatrix}n-1\k-1end{bmatrix}inom{k}{m}+(n-1)sum_{k=m}^{n-1}egin{bmatrix}n-1\kend{bmatrix}inom{k}{m}\ =sum_{k=m}^nleft(egin{bmatrix}n-1\k-1end{bmatrix}+(n-1)egin{bmatrix}n-1\kend{bmatrix} ight)inom{k}{m}=sum_{k=m}^negin{bmatrix}n\kend{bmatrix}inom{k}{m} ]

    斯特林套路

    这道题求的是:

    [ans=sum_{i=1}^negin{bmatrix}n\iend{bmatrix}i^m\ =sum_{i=1}^negin{bmatrix}n\iend{bmatrix}sum_{j=0}^megin{Bmatrix}m\jend{Bmatrix}j!inom{i}{j}\ =sum_{j=0}^megin{Bmatrix}m\jend{Bmatrix}j!sum_{i=1}^negin{bmatrix}n\iend{bmatrix}inom{i}{j}\ =sum_{j=0}^megin{Bmatrix}m\jend{Bmatrix}j!egin{bmatrix}n+1\j+1end{bmatrix} ]

    (O(nm)) 预处理第一类斯特林数,(O(m^2)) 预处理第二类斯特林数,就可以 (O(m)) 回答一个询问了

    Topcoder的评测机很垃圾,感觉在给我随机打分。前后相差只有一行注释的两次提交都能得不同的分。

    要想AC这题必须要把阶乘预处理到 (n),我也不知道为什么。

    int S1[100010][310],S2[310][310],fac[100010];
    
    void init(int n,int m){
    	S1[0][0]=1;
    	for(int i=1;i<=n+1;++i)for(int j=1;j<=min(i,m+1);++j)
    		S1[i][j]=add(S1[i-1][j-1],mul(i-1,S1[i-1][j]));
    	S2[0][0]=1;
    	for(int i=1;i<=m;++i)for(int j=1;j<=i;++j)
    		S2[i][j]=add(S2[i-1][j-1],mul(j,S2[i-1][j]));
    	fac[0]=1;
    	for(int i=1;i<=n;++i) fac[i]=mul(fac[i-1],i);
    }
    int solve(int n,int m){
    	if(m==0) return fac[n];
    	int ans=0;
    	for(int i=0;i<=m;++i) ans=add(ans,mul(S2[m][i],mul(fac[i],S1[n+1][i+1])));
    	return ans;
    }
    
    class CyclesNumber{
    public:
    	vector<int> getExpectation(vector<int> n,vector<int> m){
    		init(1e5,300);
    		vector<int> ans(n.size());
    		for(int i=0;i<(int)n.size();++i) ans[i]=solve(n[i],m[i]);
    		return ans;
    	}
    };
    

    Everything on It

    求有多少个子集族,满足:

    1. 其中任意一个子集都是 ([n]) 的子集;

    2. 任意两个子集互不相同;

    3. (1, 2, · · · , n) 都在其中至少出现了 (2) 次。

    答案对 (M) 取模。(2 ≤ N ≤ 3000, 10^8 ≤ M ≤ 10^9 + 9)(M) 是质数。

    题解

    戴大爷教会我推式子不必一步到位。

    [ans=sum_{i=0}^n(-1)^iinom{n}{i}F(i) ]

    其中 (F(i)) 表示 (1sim i) 出现次数小于等于 (1) 的方案数。

    如何求 (F(i)) 呢?我们显然可以把所有集合分为两部分:含有 (1sim i) 的和不含 (1sim i) 的。我们可以把方案按照第一类集合的数量分类计算。

    [F(i)=2^{2^{n-i}}sum_{j=0}^iG(i,j)(2^{n-i})^j ]

    其中 (G(i,j)) 表示把分 (1sim i)(j) 个非空盒子,但是有的球可以扔掉的方案数。显然有

    [G(i,j)=sum_{k=0}^iinom{i}{k}egin{Bmatrix}i-k\jend{Bmatrix}\ =sum_{k=0}^iinom{i}{i-k}egin{Bmatrix}i-k\jend{Bmatrix}\ =sum_{k=0}^iinom{i}{k}egin{Bmatrix}k\jend{Bmatrix}=egin{Bmatrix}i+1\j+1end{Bmatrix} ]

    戴大爷的组合意义:

    可以在 (j) 个集合之外新增一个集合表示垃圾堆,但是这个集合是可以为空的。怎么办呢?再新增一个 (0) 号球,这个球在哪个集合里面就说明哪个集合是垃圾堆。容易发现原方案与新构造的方案一一对应。

    这个事情告诉我们,只要具体数学学得好,推公式那都不是事儿。什么构造,不存在的。

    [ans=sum_{i=0}^n(-1)^iinom{n}{i}2^{2^{n-i}}sum_{j=0}^iegin{Bmatrix}i+1\j+1end{Bmatrix}(2^{n-i})^j ]

    时间复杂度 (O(n^2log m))

    CO int N=3000+10;
    int C[N][N],S[N][N],B[N];
    
    int main(){
    	int n=read<int>();read(mod);
    	for(int i=0;i<=n;++i){
    		C[i][0]=C[i][i]=1;
    		for(int j=1;j<i;++j) C[i][j]=add(C[i-1][j-1],C[i-1][j]);
    	}
    	S[0][0]=1;
    	for(int i=1;i<=n+1;++i)for(int j=1;j<=i;++j)
    		S[i][j]=add(S[i-1][j-1],mul(j,S[i-1][j]));
    	B[0]=1;
    	for(int i=1;i<=n;++i){
    		B[i]=B[i-1]<<1;
    		if(B[i]>=mod-1) B[i]-=mod-1;
    	}
    	int ans=0;
    	for(int i=0;i<=n;++i){
    		int sum=0;
    		for(int j=0;j<=i;++j) sum=add(sum,mul(S[i+1][j+1],fpow(2,(n-i)*j)));
    		sum=mul(sum,mul(C[n][i],fpow(2,B[n-i])));
    		ans=add(ans,i&1?mod-sum:sum);
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    LAMP网站架构解释
    ftp--pureftpd1.0.46
    给远程主机起别名
    ssh修改端口号并进行远程访问
    ssh使两台机器建立连接
    Linux搭建svn服务
    centos上git搭建
    centos上Jenkins搭建
    kvm安装准备
    服务器Java环境配置
  • 原文地址:https://www.cnblogs.com/autoint/p/12119076.html
Copyright © 2020-2023  润新知