zoukankan      html  css  js  c++  java
  • cogs 2691. Sumdiv

    2691. Sumdiv

    ★★★   输入文件:sumdiv.in   输出文件:sumdiv.out   简单对比
    时间限制:1 s   内存限制:12 MB

    【题目描述】

    考虑两个自然数A和B.定义S是A ^ B的所有自然因数的总和。确定S模9901的值。

    【输入格式】

    唯一的行包含由空格分隔的两个自然数A和B(0 <= A,B <= 50000000)。

    【输出格式】

    输出一行,即S模9901。

    【样例输入】

    2 3

    【样例输出】

    15

    样例解释:2 ^ 3 = 8。 8的自然因数是:1,2,4,8。他们的和是15。 15模9901是15(应该输出)。

    【来源】

    POJ1845

    /*
    题意:求A^B 所有约数(因子)之和mod 9901。
    
    应用质因数分解+约数和公式+逆元+等比数列求和公式
    A=p1^k1*p2^k2*...pn^kn
    A^B=p1^(k1*B)*p2^(k2*B)...pn^(kn*B)
    约数和公式:Sum=(1+p1+p1^2+...+p1^k1)*(1+p2+p2^2+...+p2^k2)*(......pk^kn)
    Sum(A^B)=(1+p1+p1^2+...+p1^k1*B)*(1+p2+p2^2+...+p2^k2*B)*(......pk^kn*B) mod 9901
    对于每一个 (1+p1+p1^2+...+p1^k1*B),根据等比数列求和公式为 [1-p1^(1+k1*B)]/(1-p1) mod 9901
    根据逆元公式:a/b mod m=(a mod mb )/b 
    原式= [p1^(k1*B+1)-1] mod [9901*(p1-1)] / (p1-1)
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define ll long long
    #define mod 9901
    #define N 10005
    int p[N],cnt;
    ll A,B;
    bool prime[N];
    void Isprime(){
        for(int i=2;i<N;i++)
            if(!prime[i]){
                p[++cnt]=i;
                for(int j=i+i;j<N;j+=i)
                    prime[j]=1;
            }
    }
    ll slow_mul(ll a,ll b,ll m){
        ll result=0;a%=m;
        while(b){
            if(b&1){result=(result+a)%m;}
            b>>=1;
            a=(a+a)%m;
        }
        return result;
    }
    ll fast_pow(ll a,ll b,ll m){
        ll result=1;a%=m;
        while(b){
            if(b&1)result=slow_mul(result,a,m);
            b>>=1;
            a=slow_mul(a,a,m);
        }
        return result;
    }
    int main(){
        freopen("sumdiv.in","r",stdin);
        freopen("sumdiv.out","w",stdout);
        //freopen("cola.txt","r",stdin);
        scanf("%lld%lld",&A,&B);
        if(A==0){printf("0");return 0;}
        Isprime();
        ll ans=1;
        for(int i=1;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=mod*(p[i]-1);
                ans*=(fast_pow(p[i],num*B+1,M)-1)/(p[i]-1);
                ans%=mod;
            }
        }
        if(A>1){
            ll M=(A-1)*mod;
            ans*=(fast_pow(A,B+1,M)-1)/(A-1);
            ans%=mod;
        }
        printf("%lld",ans);
    }
  • 相关阅读:
    MicXP程序爱好者
    cnblogs上的mysql学习心得
    iwebship 购物系统 PHP lamp环境
    可以购买的网址
    模板网址
    学习ecshop 教程网址
    ecshop数据库操作函数
    yzoj1568: 数字组合 题解
    yzoj1891 最优配对问题 题解
    yzoj1985 最长公共单调上升子序列 题解
  • 原文地址:https://www.cnblogs.com/thmyl/p/6937752.html
Copyright © 2011-2022 走看看