首页 > 代码库 > HDU 4196
HDU 4196
很容易由算术基本定理知道,完全平方数就是所有质因子指数为偶数的数。而求得N以下的质因子,可由前两篇的公式知,由N!与p的关系求得。对于指数为p的,用N!除去就可以,因为p必定属于N以内,且无重复。
至于除法,在下实在不会,学得别人的,记录一下。
MOD数除法,可以由费马小定理a^(p-1)=1 (mod p)其中p为素数,求得。因为X/Y即是X*(1/Y),为乘上逆元,所以由费马小定理知a^(p-2)即是逆元。用数乘上即可。
而对于p-2比较大的情况,只能用快速幂取模的方法求解了。
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>using namespace std;const __int64 Maxp=10000010;const __int64 MOD=1000000007;bool isprime[Maxp];__int64 prime[Maxp],nprime;__int64 adds[Maxp];void Doprime(){ nprime=0; memset(isprime,true,sizeof(isprime)); isprime[1]=false; for(__int64 i=2;i<Maxp;i++){ if(isprime[i]){ prime[nprime++]=i; for(__int64 j=i*i;j<Maxp;j+=i) isprime[j]=false; } }}__int64 Pow(__int64 anst,__int64 poe){ __int64 ret=1; __int64 tmp=anst; while(poe){ if(poe&1) ret=(ret*tmp)%MOD; tmp=(tmp*tmp)%MOD; poe=(poe>>1); } return ret;}int main(){ __int64 anst; Doprime(); adds[1]=1; for(__int64 i=2;i<Maxp;i++) adds[i]=(adds[i-1]*i)%MOD; __int64 n; while(scanf("%I64d",&n),n){ anst=1; for(__int64 i=0;prime[i]<=n&&i<nprime;i++){ __int64 c=0; for(__int64 t=prime[i];t<=n;t*=prime[i]) c+=(n/t); if(c&1) anst=(anst*prime[i])%MOD; } printf("%I64d\n",((adds[n]*Pow(anst,MOD-2))%MOD)); } return 0;}
HDU 4196
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。