洛谷T420637 组合数(c)

题目大意

T T T 组询问:

给定 n n n。请你求出下面式子对 1 0 9 + 7 10^9+7 109+7 取模的结果。
∑ i = 0 n ( n i ) 2 \sum_{i=0}^{n}\binom{n}{i}^2 i=0n(in)2
T T T 行,每行一个整数表示当次询问的答案对 1 0 9 + 7 10^9+7 109+7 取模的结果。

n = 3 n=3 n=3 时组合数依次为 1 , 3 , 3 , 1 1,3,3,1 1,3,3,1。故 1 + 9 + 9 + 1 = 20 1 + 9 + 9 + 1 = 20 1+9+9+1=20

对于 50 % 50\% 50% 的数据: 1 ≤ T , n ≤ 1000 1 \le T,n\le 1000 1T,n1000

对于 100 % 100\% 100% 的数据: 1 ≤ T , n ≤ 1 0 6 1 \le T,n \le 10^6 1T,n106

50分做法

只需要用杨辉三角递推即可

f[i][1]=1
f[i][j]=(f[i-1][j]+f[i-1][j-1])

每一次用f[i][0]来储存答案ans

而在这道题中ans=ans+f[i][j]×f[i][j]

最后只需输出f[i][0]即可

code↓

#include 
#define ll long long
using namespace std;
const int mod=1e9+7;
ll n,t,f[10005][10005],sum=0;
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	cin>>t;
	f[1][0]=sum=2,f[1][1]=f[1][2]=1;
	while(t--){
		cin>>n;
		for(int i=sum;i<=n;i++){
			ll ans=1;
			f[i][1]=1;
			for(int j=2;j<=n+1;j++){
				f[i][j]=(f[i-1][j]+f[i-1][j-1])%mod;
				ans=(ans+(f[i][j]%mod)*(f[i][j]%mod))%mod;
			}
			f[i][0]=ans;
			sum++;
		}
		cout<<f[n][0]<<endl;
	}
	return 0;
}

100分做法

最后一个等号的式子可以看成,从 2 n 2n 2n 里选 n n n 个小球出来,假设前 n n n个球选了 i i i个,那么后面的 n n n个球就要选 n − i n-i ni

那么枚举 0 0 0 n n n的所有可能性,答案就是

code↓

#include 
using namespace std;
const int N=1e6+5;
const long long mod=1e9+7;
int t;
long long n;
long long a[N*2],f[N];
long long fst (long long x, long long y) {
	long long ans=1,base=x;
	while (y > 0) {
		if(y&1) ans=ans*base%mod;
		base=base*base%mod;
		y>>=1;
	}
	return ans;
}
long long C(long long n, long long m) {
	if(n<m) return 0;
	return a[n]*fst(a[m],mod-2)%mod*fst(a[n-m],mod-2)%mod;
}

int main(){
	a[0]=1;
	for (int i=1;i<=2*N;++i) a[i]=a[i-1]*i%mod;
	for (int i=1;i<=N;++i) f[i]=C(2*i,i);
	scanf("%d", &t);
	while(t--){
		long long n;
		scanf ("%lld", &n);
		printf ("%lld\n", f[n]);
	}
	return 0;
}
//code:Vlixel

你可能感兴趣的:(luogu_topic,c语言,开发语言)