zoukankan      html  css  js  c++  java
  • POJ1845(约数之和)

    自闭的人的题解

    POJ1845 约数之和

    题目描述:
    给你两个整数A、B,让你求出a^b中所有的约数的和膜上9901的值。
    输入 :
    两个正整数A,B
    输出 :
    一个正整数表示答案
    样例:
    IN :2 3
    OUT : 15


    这道题,我一开始其实是只有暴力的思路的。
    但是,又重新去思考一下,因为求的是所有约数的和,所以我们就可以将A分解质因数

    [A=p_{1}^{c_{1}} * p_{2}^{c_{2}} * p_{3}^{c_{3}} * ldots * p_{n}^{c n_{+1}} ]

    又因为要^B,所以我们最后得到的式子就是这个:

    [mathrm{A}=p_{1}^{B * c_{1}} * p_{2}^{B * c_{2}} * p_{3}^{B * c_{3}} * ldots * p_{n}^{B * c_{n}} ]

    所以A^B的约数为就是:

    [egin{array}{c}{left{p_{1}^{k_{1}} * p_{2}^{k_{2}} * ldots * p_{n}^{k_{n}} ight}} \ {0 leq k_{i} leq B * c_{i}(1 leq i leq n)}end{array} ]

    再将中间的约数拆开来,得到:

    [left(1+p_{1}+p_{1}^{2}+p_{1}^{3}+p_{1}^{4} ldots+p_{1}^{B cdot c_{1}} ight) *left(1+p_{2}+p_{2}^{2}+p_{2}^{3}+p_{2}^{4} ldots+p_{2}^{B cdot c_{2}} ight) ldots *left(1+p_{n}+p_{n}^{2}+p_{n}^{3}+p_{n}^{4} ldots+p_{n}^{B cdot c_{n}} ight) ]

    所以我们的问题就转化到了对于这个式子进行取模求和,但是,我们如何进行求和呢?
    因为其中全部都是等比数列,所以如果我们就可以考虑使用等比数列求和公式进行求解,但是,我们这中间有除法,所以我们的取模操作就会出问题。所以这个思路的正确性是无法保证的。
    我们可以再换一种思路,可以将问题进行

    分治

    我们设出一个函数sum(p,c)表示约数对答案造成的影响。

    [operatorname{sum}(p, c)=1+p+p^{2}+p^{3}+p^{4} ldots+p^{c} ]

    我们考虑对于c为奇数时,

    [egin{aligned} operatorname{sum}(p, c) &=1+p+p^{2}+p^{3}+p^{4} ldots+p^{c} \ &=left(1+p+cdots+p^{frac{c-1}{2}} ight)+left(p^{frac{c+1}{2}}+cdots+p^{c} ight) \ &=left(1+p+cdots+p^{frac{c-1}{2}} ight)+p^{frac{c+1}{2}}left(1+p+cdots+p^{frac{c-1}{2}} ight) \ &=left(1+p+cdots+p^{frac{c-1}{2}} ight) *left(1+p^{frac{c+1}{2}} ight) \ &=left(1+p^{frac{c+1}{2}} ight) * operatorname{sum}left(p, frac{c-1}{2} ight) end{aligned} ]

    当c为偶数时,同理为了满足我们刚刚推出来的式子,我们把最后一个p单独拿出来,这样我们就可以得到跟奇数一样的情况。
    所以偶数的公式为:

    [operatorname{sum}(p, c)=left(1+p^{frac{c}{2}} ight) * operatorname{sum}left(p, frac{c}{2}-1 ight)+p^{c} ]

    这样,我们两个公式都已经推出来了,我们就可以进行操作(具体细节在代码中显示)。
    代码:

    
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    template <typename type>
    void scan(type &x){
        type f=1;x=0;char s=getchar();
        while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
        while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
        x*=f;
    }
    #define mod 9901
    #define int ll
    #define ll long long
    ll ksm(ll a,ll b){
        ll ans=1;
        while(b){
            if(b&1){
                ans=ans*a%mod;
            }
            a=(a*a)%mod;
            b>>=1;
        }
        return ans%mod;
    }\快速幂
    ll sum(ll p,ll c){
        if(c==0){
            return 1;
        }
        if(c&1){
            return (1+ksm(p,(c+1)>>1)%mod)*sum(p,(c-1)>>1)%mod;//如果为奇数
        }else{
            return (1+ksm(p,c>>1)%mod)*sum(p,(c>>1)-1)%mod+ksm(p,c)%mod;//如果为偶数
        }
    }//进行操作
    ll a,ans,b;
    
    signed main(){
        scan(a);
        scan(b);
        ans=1;
        for(int i=2;i<=a;i++){
            int num=0;
            while(a%i==0){
                num++;
                a/=i;
            }
            if(num)
            ans=ans*sum(i,b*num)%mod;
        }
        if(a==0){
            puts("0");
        }else{
            printf("%lld
    ",ans%mod);  
        }
        
        return 0;
    }
    
  • 相关阅读:
    LR学习笔记八 之 初识LR动态链接库
    LR学习笔记七 之 LR录制sql脚本
    LR学习笔记三 之 界面分析
    LoadRunner学习笔记一
    LR学习笔记四 之 调试、日志、动态运行
    协调世界时间 UTC
    InnerText和InnerXml的区别
    避免 showModalDialog 弹出新窗体
    嵌套SELECT语句
    XmlElement和XmlNode的区别
  • 原文地址:https://www.cnblogs.com/xishirujin/p/11411077.html
Copyright © 2011-2022 走看看