poj 1845 Sumdiv [素数筛+母函数]

题意:给你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[N],np;  
bool vis[N];  
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[N],num[N],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);
	}
	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值