poj 1845 Sumdiv [素数筛+母函数]
2017-08-02 15:43
218 查看
题意:给你A和B,求A^B的所有约数的和
题解:可以求解A的质因子(1~sqrt(n)个素数)有哪些,然后根据母函数的特性,(2^0+2^1+2^2·····)*(3^0+3^1+3^2····)····的结果就是所有质因子组合后,所有约数的和,特别要注意这里不能用费马小定理或者扩展欧几里得求逆元,因为可能存在gcd(a,mod)!=1的情况,要二分求解答案。
AC代码:
题解:可以求解A的质因子(1~sqrt(n)个素数)有哪些,然后根据母函数的特性,(2^0+2^1+2^2·····)*(3^0+3^1+3^2····)····的结果就是所有质因子组合后,所有约数的和,特别要注意这里不能用费马小定理或者扩展欧几里得求逆元,因为可能存在gcd(a,mod)!=1的情况,要二分求解答案。
AC代码:
#include<stdio.h> #include<string.h> #include<iostream> #define N 10005 #define mod 9901 using namespace std; typedef long long ll; ll prime ,np; bool vis ; void get_prime2() { np = 0; memset(vis, 0, sizeof(vis)); for (ll i = 2; i < N; ++i) { if (!vis[i]) prime[np++]=i; for (ll j = 0,t ; j < np && (t = prime[j]*i) < N; ++j) { vis[t] = 1; if(i % prime[j] == 0) break; } } } ll qmi(ll a,ll b) { a%=mod; ll ans=1; while(b) { if(b%2==1)ans=(ans*a)%mod; a=(a*a)%mod; b/=2; } return ans; } ll who ,num ,top; void div(ll x) { for(ll i=0;i<np;i++) if(x%prime[i]==0) { who[top]=prime[i]; while(x%prime[i]==0) num[top]++,x/=prime[i]; top++; } if(x!=1) { who[top]=x; num[top]=1; top++; } } ll sum(ll p,ll n) { if(p==0)return 0; if(n==0)return 1; if(n&1) { return ((1+qmi(p,n/2+1))%mod*sum(p,n/2)%mod)%mod; } else return ((1+qmi(p,n/2+1))%mod*sum(p,n/2-1)+qmi(p,n/2)%mod)%mod; } int main() { get_prime2(); ll a,b; while(cin>>a>>b) { memset(num,0,sizeof(num)); top=0; div(a); for(ll i=0;i<top;i++) num[i]=num[i]*b; ll haha=1; for(ll i=0;i<top;i++) { haha=(haha*sum(who[i],num[i]))%mod; } printf("%lld\n",haha); } }
相关文章推荐
- poj 1845 Sumdiv 素数筛+快速幂求逆元+二分乘法
- poj 1845 Sumdiv
- POJ 1845 Sumdiv 简单数论问题
- 【POJ 1845】 Sumdiv (整数唯分+约数和公式+二分等比数列前n项和+同余)
- 【数论】【poj1845】Sumdiv
- POJ_1845 Sumdiv
- 【POJ 1845】Sumdiv
- poj 1845 Sumdiv
- poj 1845 Sumdiv(所有约数的和)
- Sumdiv(poj 1845)
- POJ 1845 Sumdiv(快速幂取模+快速分解因式)
- Sumdiv POJ - 1845
- poj 1845 Sumdiv (很多数论知识 ,很经典 )
- poj 1845 Sumdiv——数论
- POJ 1845 - Sumdiv
- poj 1845 Sumdiv
- POJ 1845 Sumdiv(高中数学,推公式,分治)
- 【数论】POJ_1845_Sumdiv
- poj 1845 Sumdiv (数论)
- POJ1845-Sumdiv大数约数和