您的位置:首页 > 其它

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代码:

#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);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: