题目描述:
In the Republic of Remoteland, the people celebrate their independence day every year. However, as it was a long long time ago, nobody can remember when it was exactly. The only thing people can remember is that today, the number of days elapsed since their independence (D) is a perfect square, and moreover it is the largest possible such number one can form as a product of distinct numbers less than or equal to n.
As the years in Remoteland have 1,000,000,007 days, their citizens just need D modulo 1,000,000,007. Note that they are interested in the largest D, not in the largest D modulo 1,000,000,007.
Input:
Every test case is described by a single line with an integer n, (1<=n<=10,000, 000). The input ends with a line containing 0.
Output:
For each test case, output the number of days ago the Republic became independent, modulo 1,000,000,007, one per line.
Sample Input:
4
9348095
6297540
0
Sample Output:
4
177582252
644064736
题解:
1、打素数表
2、计算 n! 中含有素因子个数,如果为奇数就保留这个素因子的乘积,以便最后相除
3、求出除法结果
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 1000000007
#define maxn 10000005
#define INF 0x3f3f3f3f
int v[maxn], prime[maxn][2];//prime[i][0]是记录质数p,prime[i][1]是记录质数p的个数
int m = 0;
ll jiecheng[maxn];//阶乘打表
void xianxing(int n)//线性筛
{
for (int i = 2; i <= n; i++)
{
if (v[i] == 0)
{
v[i] = i;
prime[++m][0] = i;
}
for (int j = 1; j <= m; j++)
{
if (prime[j][0] > v[i] || prime[j][0] * i > n)
{
break;
}
v[i*prime[j][0]] = prime[j][0];
}
}
}
ll quickpow(ll a, ll b, ll c)
{
if (b == 0)return 1;
if (b == 1)return a;
else
{
if (b % 2 == 0)
{
ll t = quickpow(a, b / 2, c);
return t * t%c;
}
else
{
ll t = quickpow(a, b / 2, c);
t = t * t%c;
return t * a%c;
}
}
}
int main()
{
xianxing(10000000);
int n;
ll temp = 1;//记录阶乘的
jiecheng[1] = 1;
for (int i = 2; i <= 10000000; i++)//阶乘打表
{
temp = temp * i%mod;
jiecheng[i] = temp;
}
while (~scanf("%d", &n) && n)
{
ll gg = 1;
ll result = 1;
for (int i = 1; i <= m; i++)//记录质数p的个数的表初始化
{
if (prime[i][0] > n)break;
prime[i][1] = 0;
}
ll temp2 = 1;
for (int i = 1; i <= m; i++)//利用n!中p(p为质数)的个数为 求和n/(p的k次方) ,k为1到正无穷,将n!质因数分解
{
gg = 1;
if (prime[i][0] > n)break;//质数都比输入的大了,没必要去判断了,直接break
for (int j = 1; j <= 1000000; j++)
{
gg *= prime[i][0];
if (n / gg == 0)break;//后面全为0,加了也没意义,直接break
prime[i][1] += int(n / gg);
}
if (prime[i][1] % 2 == 1)temp2 = temp2 * prime[i][0] % mod;//记录奇因子的乘积
}
//D mod p = [(n!) mod p]∗[(奇数个因子的乘积)mod p]p−2
result = (jiecheng[n] * quickpow(temp2, mod - 2, mod)) % mod;
printf("%lld\n", result);
}
}