hdu 5201 The Monkey King 母函数 泰勒展开

题意:

有n个苹果,m个人,要求分给第一个人最多,其他人随意,求有多少种分法。最后结果模1000000007。

限制:

1 <= n,m <= 100000

思路:

母函数,泰勒展开

枚举第一个人分到的苹果,设为u,

剩下的苹果为n-u个,分成m-1份,则有:

生成函数为:

G(x)=(1+x+x^2+...+x^(u-1))^(m-1)

=> G(x)=((1-x^u)/(1-x))^(m-1)

=> G(x)=(1-x^u)^(m-1) / (1-x)^(m-1)

=> G(x)=(1-x^u)^(m-1) * (1-x)^(1-m) ---一式

对于任意二项式,其泰勒展开为:

(1+x)^k = 1 + kx + k(k-1)/2!*x^2 + ... + k(k-1)...(k-n+1)/n!x^k + ...

对"一式"进行泰勒展开,得到两个多项式相乘,然后对于每个u,就能通过求"一式"的x^(n-u)的系数,求结果。

/*hdu 5201 The Monkey King
  题意:
  有n个苹果,m个人,要求分给第一个人最多,其他人随意,求有多少种分法。最后结果模1000000007。
  限制:
  1 <= n,m <= 100000
  思路:
  母函数,泰勒展开
  枚举第一个人分到的苹果,设为u,
  剩下的苹果为n-u个,分成m-1份,则有:
  生成函数为:
  G(x)=(1+x+x^2+...+x^(u-1))^(m-1)
  => G(x)=((1-x^u)/(1-x))^(m-1)
  => G(x)=(1-x^u)^(m-1) / (1-x)^(m-1)
  => G(x)=(1-x^u)^(m-1) * (1-x)^(1-m)	---一式

  对于任意二项式,其泰勒展开为:
  (1+x)^k = 1 + kx + k(k-1)/2!*x^2 + ... + k(k-1)...(k-n+1)/n!x^k + ... 

  对"一式"进行泰勒展开,得到两个多项式相乘,然后对于每个u,就能通过求"一式"的x^(n-u)的系数,求结果。
 */
#include<iostream>
#include<cstdio>
using namespace std;
#define LL __int64
const int MOD=1000000007;
const int N=1000005;
LL inv(LL a,LL m){
	LL p=1,q=0,b=m,c,d;
	while(b>0){
		c=a/b;
		d=a; a=b; b=d%b;
		d=p; p=q; q=d-c*q;
	}
	return p<0?p+m:p;
}
LL fac[N],ny[N];
void predo(){
	fac[0]=1;
	ny[0]=inv(fac[0],MOD);
	for(int i=1;i<N;++i){
		fac[i]=fac[i-1]*i%MOD;
		ny[i]=inv(fac[i],MOD);
	}
}
LL C(int n,int m){
	if(m<0 || n<m) return 0;
	return fac[n]*ny[m]%MOD*ny[n-m]%MOD;
}
int main(){
	int T;
	int n,m;
	predo();
	scanf("%d",&T);
	while(T--){
		scanf("%d%d",&n,&m);
		if(m==1){
            puts("1");
            continue;
        }
		LL ans=0;
		for(int i=1;i<=n;++i){
			LL fu=1;
			for(int j=0;j*i<=n-i && j<m;++j){
				ans=(ans+C(n-i-j*i+m-2,n-i-j*i)*C(m-1,j)*fu%MOD+MOD)%MOD;
				fu=-fu;
			}
		}
		printf("%I64d\n",ans);
	}
	return 0;
}

时间: 2024-10-16 11:36:23

hdu 5201 The Monkey King 母函数 泰勒展开的相关文章

HDU 5201 The Monkey King(容斥)

看了斌神的题解恍然大悟http://www.kuangbin.net/archives/bc36 代码: #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; typedef long long ll; const int MOD = 1000000007; const int N = 200005; int t, n, m, f[N], rf[N]; int p

【HDU 1512】Monkey King

Monkey King Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3423    Accepted Submission(s): 1479 Problem Description Once in a forest, there lived N aggressive monkeys. At the beginning, they

ZOJ 2334 HDU 1512 Monkey King

题意: 猴子们打架  认识的猴子不会打架  两只猴子打完以后就认识了  A认识B B认识C A也认识C  每次打架由两伙猴子进行  分别选出自己的最高战斗力  在战斗之后两只猴子战斗力减半  给出m次打架  输出打架后这一伙猴子里的最强战斗力 思路: 判断两只猴子是不是一伙的  用到并查集 快速找出一伙猴子中的最强战斗力用到堆  但打完架两伙猴子合并时堆需要nlogn复杂度  因此用左偏树代替堆 代码: #include<cstdio> #include<cstring> #inc

Monkey King HDU - 1512 (左偏树)

Monkey King HDU - 1512 忽然看到左偏树,挺简单的,抄了个模板题练练 1 //左偏树 2 #include <bits/stdc++.h> 3 using namespace std; 4 const int maxn = 100010; 5 struct Node{ 6 int val, dis, l, r; 7 }p[maxn]; 8 int f[maxn]; 9 int gf(int x){ 10 return x == f[x] ? f[x] : f[x] = gf

数据结构(左偏树):HDU 1512 Monkey King

Monkey King Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4714    Accepted Submission(s): 2032 Problem Description Once in a forest, there lived N aggressive monkeys. At the beginning, they e

hdu 1085 Holding Bin-Laden Captive!(母函数)

http://acm.hdu.edu.cn/showproblem.php?pid=1085 题意:1元,2元,5元的硬币分别有num[1],num[2],num[3]个.问用这些硬币不能组合成的最小钱数. 继续母函数. 有两个注意的地方: 对c2[]初始化的同时也要对c1[]初始化. 最后枚举到sum+1,因为存在[1,sum]都可以凑成的可能,这时输出sum+1. #include <stdio.h> #include <iostream> #include <map&g

hdu 1398 Square Coins(母函数|完全背包)

http://acm.hdu.edu.cn/showproblem.php?pid=1398 题意:有价值为1^2,2^2....7^2的硬币共17种,每种硬币都有无限个.问用这些硬币能够组成价值为n的钱数共有几种方案数. 母函数: #include <stdio.h> #include <iostream> #include <map> #include <set> #include <stack> #include <vector>

hdu 2082 找单词(母函数|多重背包)

http://acm.hdu.edu.cn/showproblem.php?pid=2082 每一个字母的价值固定,但数目不定.所以每个字母对应的表达式也不同,若第i个字母的个数为a[i],价值为i,那么它的母函数为(1+x^i+x^(2i)+.....+x^(a[i]*b[i])).那么将i属于[1,26]的母函数相乘得到的x^m(1<=m<=50)的系数相加就是答案. #include <stdio.h> #include <iostream> #include &

[HDU1512]:Monkey King

Monkey King Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6274    Accepted Submission(s): 2678 Problem Description Once in a forest, there lived N aggressive monkeys. At the beginning, they e