[JZOJ4900]完全平方数

来源:互联网 发布:答题软件哪个好 编辑:程序博客网 时间:2024/05/16 00:50

题目大意

给定n,求用任意个不大于n的不同正整数相乘得到的最大的完全平方数是多少。
答案对108+7取模。

1n5×106


题目分析

这题的Trick不错,考场上我居然弱弱地没有想出来QwQ
显然出了贪心这种题目不可做了~
我们先把1n所有数都乘起来,然后再去掉不能取的。
一个数是完全平方数当且仅当它的所有质因子的幂数都是偶数。
那么我们考虑一个质因子,如果它在n的阶乘中的幂数是奇数,我们要怎么办?显然是删掉这个质数是最优的!这样其它的数都能保留下来。
我们线筛一下,分解质因数就好了。虽然带个log,但是还是很快的。
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;}
0 0
原创粉丝点击