POJ 1845 Sumdiv(数论)

题目链接
题意:求AB 的约数和。 A B范围 5e7

解题思路:在这里插入图片描述
(( mark 有点难写

ll mult(ll a, ll b, ll c)
{
    ll ans = 0;
    while(b)
    {
        if(b & 1)
            ans = (ans+a)%c;
        b>>=1;
        a = (a+a)%c;
    }
    return ans;
}

ll pow_mod(ll x,ll n,ll mod)
{
    ll res=1;
    while(n)
    {
        if(n&1)
            res=mult(res,x,mod);
        x=mult(x,x,mod);
        n>>=1;
    }
    return res;
}

const int manx=1e6+7;

//vector<ll>v[manx];
ll fac[manx/100];//质因子
ll num[manx/100]; //幂次
ll rnm=0;
ll cnt=0,ans=1;


ll p[manx];

bool prime[manx];
void isprime()
{
    cnt= 0;
    memset(prime, 0, sizeof(prime));
    prime[1] = 1;
    for(int i=2; i<manx; i++)
    {
        if(!prime[i])
        {
            p[++cnt] = i;
            for(int j=i+i; j<manx; j+=i)
                prime[j] = 1;
        }
    }
}
void check(ll x)   //质因子分解
{
    rnm=0;
    memset(num,0,sizeof(num));
    for(int j=1; j<=cnt; j++)
    {
        if(p[j]*p[j]>x)
            break;
        ll xx=0;
        if(x%p[j]==0)
        {
            while(x%p[j]==0)
                x/=p[j],xx++;
            rnm++;
            fac[rnm]=p[j];
            num[rnm]=xx;
        }
    }
    if(x>1)
    {
        rnm++;
        fac[rnm]=x;
        num[rnm]=1;
    }
}
int main()
{
    isprime();
    ll a,B;
    while(scanf("%lld%lld",&a,&B)!=EOF)
    {
        check(a); //素因子分解
        ll ans=1,tmp;
        for(int i=1; i<=rnm; i++)
        {
            ll MM=(fac[i]-1)*mods;
            tmp=pow_mod(fac[i],num[i]*B+1,MM);
            tmp--;
            tmp=(tmp%MM+MM)%MM;
            tmp/=(fac[i]-1);
            ans=(ans*tmp)%mods;
        }
        ans=(ans%mods+mods)%mods;
        printf("%lld\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值