题目大意
给定
n
,求用任意个不大于
答案对
108+7
取模。
1≤n≤5×106
题目分析
这题的Trick不错,考场上我居然弱弱地没有想出来QwQ
显然出了贪心这种题目不可做了~
我们先把
1
到
一个数是完全平方数当且仅当它的所有质因子的幂数都是偶数。
那么我们考虑一个质因子,如果它在
n
的阶乘中的幂数是奇数,我们要怎么办?显然是删掉这个质数是最优的!这样其它的数都能保留下来。
我们线筛一下,分解质因数就好了。虽然带个
O(nlog2n)
。
代码实现
#include <iostream>
#include <cstdio>
using namespace std;
const int N=5000000;
const int P=100000007;
int f[N+50],pri[N+50];
bool cnt[N+50];
int n,ans;
int quick_power(int x,int y)
{
int ret=1;
for (;y;y>>=1,x=1ll*x*x%P) if (y&1) ret=1ll*ret*x%P;
return ret;
}
void pre()
{
f[1]=1;
for (int i=2;i<=n;i++)
{
if (!f[i]) f[i]=i,pri[++pri[0]]=i;
for (int j=1;j<=pri[0];j++)
{
if (1ll*pri[j]*i>n) break;
f[pri[j]*i]=pri[j];
if (!(i%pri[j])) break;
}
}
}
void calc()
{
ans=1;
for (int i=1,x;i<=n;i++)
{
ans=1ll*ans*i%P;
for (x=i;x!=1;x/=f[x]) cnt[f[x]]^=1;
}
for (int i=1;i<=n;i++) if (cnt[i]) ans=1ll*ans*quick_power(i,P-2)%P;
}
int main()
{
freopen("number.in","r",stdin),freopen("number.out","w",stdout);
scanf("%d",&n);
pre(),calc();
printf("%d\n",ans);
fclose(stdin),fclose(stdout);
return 0;
}