您的位置:首页 > 其它

Hdu 5407 CRB and Candies (找规律)

2015-08-21 10:07 246 查看
题目链接:

  Hdu 5407 CRB and Candies

题目描述:

  给出一个数n,求lcm(C(n,0),C[n,1],C[n-2]......C
[n-2],C
[n-1],C

)%(1e9+7)是多少?


解题思路:

  刚开始的时候各种开脑洞,然后卡题卡的风生水起。最后就上了数列查询这个神奇的网站,竟然被我找到了!!!!就是把题目上给的问题转化为求lcm(1, 2, 3, 4 ...... n-2, n-1, n, n-1) / (n+1),扎扎就打了两个表一个lcm
,区间[1,n]的最小公倍数,一个C
,代表pow(n, mod-2),每次查询就变成了O(1)。还是依旧卡的飞起(现在想起,心还是好痛),最后发现lcm数组计算的时候由于lcm的性质限制,并不能lcm
=(lcm[n-1]/gcd(lcm[n-1], n)*n)%mod。随后就开始了TLE之旅,然后就在反复计算复杂度,TLE的很迷啊。怎么计算也并不会T啊,最后换了G++就通过了。(扎扎只能说是神题。恩,没错,是神题)


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

typedef long long LL;
const int maxn = 1000005;
const int mod = 1000000007;
LL lcm[maxn], C[maxn], prim[maxn], cnt;
bool mark[maxn];

void isprim ()
{
cnt = 0;
for (int i=2; i<maxn; i++)
if (mark[i] == false)
{
prim[cnt++] = i;
for (int j=i+i; j<maxn; j+=i)
mark[j] = true;
}
}
LL Pow (LL x, LL n)
{
LL res = 1;
while (n)
{
if (n % 2)
res = (res * x) % mod;
x = (x * x) % mod;
n /= 2;
}
return res;
}
void init ()
{
for (int i=1; i<maxn; i++)
C[i] = Pow(i, mod-2);
isprim();
for (int i=0; i<cnt; i++)
{
LL x = prim[i];
while (x < maxn)
{
lcm[x] = prim[i];
x *= prim[i];
}
}
lcm[0] = 1;
for (int i=1; i<maxn; i++)
{
if (lcm[i] == 0)
lcm[i] = 1;
lcm[i] = (lcm[i-1] * lcm[i]) % mod;
}
}
int main ()
{
int t, n;
init ();
scanf ("%d", &t);
while (t --)
{
scanf ("%d", &n);
printf ("%lld\n", lcm[n+1] * C[n+1] % mod);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: