题目来源于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) imes (1+2)...(1+t)+(2+1) imes (2+2)...(2+t)+...+(n+1) imes (n+2)...(n+t))
(=sum_{i=1}^{n}(i+t)!/i!)
(=t! imes sum_{i=1}^{n}C_{i+t}^{t})
(=t! imes (C_{1+t}^t+C_{2+t}^t+C_{3+t}^t+...+C_{n+t}^t))
(=t! imes (C_{1+t}^{t+1}+C_{1+t}^t+C_{2+t}^t+C_{3+t}^t+...+C_{n+t}^t-1))
(=t! imes C_{n+t+1}^{t+1}-t!)
(=frac{(n+t+1) imes ... imes (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
",ans);
}
return 0;
}