poj 1845

来源:互联网 发布:打蛋器价格淘宝 编辑:程序博客网 时间:2024/06/07 00:27

传送门


大致题意:

求A^B的所有约数(即因子)之和,并对其取模 9901再输出。

 

解题思路:

要求有较强 数学思维 的题

应用定理主要有三个:

要求有较强 数学思维 的题

应用定理主要有三个:

(1)   整数的唯一分解定理:

      任意正整数都有且只有一种方式写出其素因子的乘积表达式。

      A=(p1^k1)*(p2^k2)*(p3^k3)*....*(pn^kn)   其中pi均为素数

(2)   约数和公式:

对于已经分解的整数A=(p1^k1)*(p2^k2)*(p3^k3)*....*(pn^kn)

有A的所有因子之和为

    S = (1+p1+p1^2+p1^3+...p1^k1) * (1+p2+p2^2+p2^3+….p2^k2) * (1+p3+ p3^3+…+ p3^k3) * .... * (1+pn+pn^2+pn^3+...pn^kn)

(3)   同余模公式:

(a+b)%m=(a%m+b%m)%m

(a*b)%m=(a%m*b%m)%m




用等比数列求和公式,但是要用逆元。用如下公式即可

 

                     

 

因为可能会很大,超过int范围,所以在快速幂时要二分乘法。


#include <iostream>#include <string.h>#include <stdio.h>using namespace std;typedef long long LL;const int N = 10005;const int MOD = 9901;bool prime[N];int p[N];int cnt;void isprime(){    cnt = 0;    memset(prime,true,sizeof(prime));    for(int i=2; i<N; i++)    {        if(prime[i])        {            p[cnt++] = i;            for(int j=i+i; j<N; j+=i)                prime[j] = false;        }    }}//1LL inv1(LL t, LL p){//求t关于p的逆元,注意:t要小于p,最好传参前先把t%p一下    return t == 1 ? 1 : (p - p / t) * inv1(p % t, p) % p;}long long pow_m(long long a,long long n)//快速模幂运算{    long long res=1;    long long tmp=a%MOD;    while(n)    {        if(n&1){res*=tmp;res%=MOD;}        n>>=1;        tmp*=tmp;        tmp%=MOD;    }    return res;}// 2LL multi(LL a,LL b,LL m){    LL ans = 0;    a %= m;    while(b)    {        if(b & 1)        {            ans = (ans + a) % m;            b--;        }        b >>= 1;        a = (a + a) % m;    }    return ans;}LL quick_mod(LL a,LL b,LL m){    LL ans = 1;    a %= m;    while(b)    {        if(b & 1)        {            ans = multi(ans,a,m);            b--;        }        b >>= 1;        a = multi(a,a,m);    }    return ans;}void Solve(LL A,LL B){    LL ans = 1;    for(int i=0; p[i]*p[i] <= A; i++)    {        if(A % p[i] == 0)        {            int num = 0;            while(A % p[i] == 0)            {                num++;                A /= p[i];            }            LL M = (p[i] - 1) * MOD;            ans *= (pow_m(p[i],num*B+1) - 1)*inv1(p[i]-1,MOD);            ans %= MOD;        }    }    if(A > 1)    {        LL M = MOD * (A - 1);        ans *= (quick_mod(A,B+1,M) + M - 1) / (A - 1);        ans %= MOD;    }    cout<<ans<<endl;}int main(){    LL A,B;    isprime();    while(cin>>A>>B)        Solve(A,B);    return 0;}



原创粉丝点击