A Easy Counting Problem
发布时间: 2017年6月10日 19:41 最后更新: 2017年6月10日 19:44 时间限制: 1000ms 内存限制: 128M
Megumin喜欢计数问题。
一天,Megumin在一个圆上画了n个点,并用线段把任意两点都连起来,她很想知道此时圆内有多少个交点。
然而,Megumin发现,即使圆上的点数n相同,圆内的交点数也不一定相同。
她很好奇,当圆上有n个点时,圆内最多有多少个交点呢?
由于结果很大,Megumin只需要知道结果对1e9+7取模的值就可以了,你能告诉她吗?
第一行是一个整数T(T<=50),表示数据组数.
接下来是T组数据.
每组数据是一个整数n(1<=n<=1e9),表示圆上有n个点.
对于每组数据输出一个整数,表示此时圆内最多的交点数,结果对1e9+7取模
1 4
1
对乘法逆元进行打表:
void init()
{
inv[1] = 1;
for (int i = 2; i <= 110000; i++)
{
inv[i] = (MOD - MOD / i) * inv[MOD%i] % MOD;
}
}
使用乘法逆元计算组合数对目标数取模的结果,这里因为题目要求所以限制了m=4,稍加修改即可以求取其他组合数对目标数取模的值:
ll Calcul(int n, int m = 4)
{
c[0] = 1;
for (int i = 1; i <= m; i++)
{
c[i] = c[i - 1] * ((n - i + 1) % MOD*inv[i] % MOD) % MOD;
c[i] = c[i] % MOD;
}
return c[m];
}
AC代码:
#include <bits/stdc++.h>
using namespace std;
#define MOD 1000000007
#define inf 0x7f7f7f7f
#define ll long long
#define ull unsigned long long
const int MAXN = 1e5+5;
ll inv[110000], c[5];
void init()
{
inv[1] = 1;
for (int i = 2; i <= 110000; i++)
{
inv[i] = (MOD - MOD / i) * inv[MOD%i] % MOD;
}
}
ll Calcul(int n, int m = 4)
{
c[0] = 1;
for (int i = 1; i <= m; i++)
{
c[i] = c[i - 1] * ((n - i + 1) % MOD*inv[i] % MOD) % MOD;
c[i] = c[i] % MOD;
}
return c[m];
}
int main()
{
memset(inv, 0, sizeof(inv));
init();
int t;
cin >> t;
while (t--)
{
memset(c, 0, sizeof(c));
int n;
cin >> n;
cout << Calcul(n) << endl;
}
return 0;
}