求和(组合数学)(逆元)

题目来源于noi.ac国庆模拟赛test4 T1

题目内容

给一个 n行 t 列的矩阵,矩阵第 i行第 j列的元素是 i+j。
定义矩阵第 i行的积为第 i行所有元素的乘积。
现在要你求矩阵所有行的积的和。答案可能很大,所以 mod 1000000007(109+7)输出。

输入格式

第一行一个整数 T表示数据组数。
后面 T 行每行两个数 n 和 t。

输出格式

一共 T 行每行一个数表示答案。答案模 \(10e9+7\)

样例输入

2
3 1
2 2

样例输出

9
18

数据范围

10%, \(T≤100,n≤1000\)
另20%, \(T≤10,n≤10^7\)
另20%,\(T≤10000,n≤10^7\)
另20%, \(T≤10000, n≤10^8\)
100%, \(1≤T≤10000,1≤n≤10^{10},1≤t≤1000\)


题目要求的就是
\((1+1)\times (1+2)...(1+t)+(2+1)\times (2+2)...(2+t)+...+(n+1)\times (n+2)...(n+t)\)
\(=\sum_{i=1}^{n}(i+t)!/i!\)

\(=t!\times \sum_{i=1}^{n}C_{i+t}^{t}\)

\(=t!\times (C_{1+t}^t+C_{2+t}^t+C_{3+t}^t+...+C_{n+t}^t)\)

\(=t!\times (C_{1+t}^{t+1}+C_{1+t}^t+C_{2+t}^t+C_{3+t}^t+...+C_{n+t}^t-1)\)

\(=t!\times C_{n+t+1}^{t+1}-t!\)

\(=\frac{(n+t+1)\times ...\times (n+1)}{t+1}-t!\)

所以程序很好写,来个逆元就可以了。

解题的关键是要对组合数的形式很熟悉,然后很快的想到组合数的转化和中间递推的推导。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define mod 1000000007
using namespace std;
long long n,t;
int m;
inline long long mul(long long x,long long y)
{
	long long ans=1;
	while(y)
	{
		if(y&1) ans=ans*x%mod;
		x=x*x%mod;
		y>>=1;
	}
	return ans%mod;
}
inline long long calc(long long x)
{
	long long ans=1;
	for(long long i=1;i<=x;i++)
		ans=ans*mul(i,mod-2)%mod;
	return ans%mod;
}
int main()
{
	scanf("%d",&m);
	while(m--)
	{
		scanf("%lld%lld",&n,&t);
		long long ans=1;
		for(long long i=n+1;i<=n+1+t;i++)
			ans=ans*i%mod;
		ans=ans*mul(t+1,mod-2)%mod;
		long long cur_ans=1;
		for(long long i=1;i<=t;i++)
			cur_ans=cur_ans*i%mod;
		ans=(ans+mod-cur_ans)%mod;
		printf("%lld\n",ans);
	}
	return 0;
}
posted @ 2018-10-16 20:31  风浔凌  阅读(377)  评论(0编辑  收藏  举报