zoukankan      html  css  js  c++  java
  • poj 1845 Sumdiv(数论+二分)

    刚开始学习数论,不知道该从哪方面学起,就找了这道题做做,希望通过做题能找到学习数论的方向。花了有两天的时间终于弄懂了这题的思想,恩,数论真的很神奇!

    题意是:求a^b的所有因子的和取余9901后的结果。

    用到的知识点有:

    1)素因子分解唯一性定理:任意正整数都能用一种方式且只有一种方式写出素数的乘积。: 60 =2^2*3*5

    2)约数和公式: 将A^B 分解成素因数形式:A^B=(p1^k1)*(p2^k2)*(p3^k3)………

    那么A^B所有因子之和就是  S=(1+p1+p1^2+p1^3+…..p1^k1)*(1+p2+p2^2+p2^3+…..p2^k2)*(1+p3+…)*…………..

    然后就是二分法求a^b和所有因子的和了。

    我觉得下面的博客写的很好,比较容易理解,可以参考一下。

    http://hi.baidu.com/aconly/blog/item/1a25845d1bfbbc44fbf2c0bf.html

     

    还有一点,就是按位与可以用来判断k的奇偶性~~

    代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define maxx 7100
    #define mod 9901
    
    __int64 p[maxx],f[maxx],s;
    
    void init()//筛选法求素数
    {
        int i,j;
        memset(f,0,sizeof(f));
        s=0;
        for(i=2;i<maxx;i++)
        {
            if(!f[i])
            {
                p[s++]=i;
                for(j=2*i;j<maxx;j+=i)
                f[j]=1;
            }
        }
    }
    
    __int64 exp(__int64 a,__int64 b)//二分计算a^b;
    {
        if(1==b)
        return a;
        __int64 k = exp(a,b/2);
        if(b&1)//判断奇偶
        return (k*k*a)%mod;
        else
        return (k*k)%mod;
    }
    
    __int64 sum(__int64 a,__int64 b)
    {
        if(b==1)
        return 1;
        __int64 k;
        k = sum(a,b/2);
        if(b&1)
        return (k+exp(a,b/2)*(1+a*k))%mod;//k为奇数时。
        else
        return ((1+exp(a,b/2))*k)%mod;//k为偶数时。
    }
    
    int main()
    {
        int a,b;
        int i,j;
    
        init();
        while (scanf("%d%d",&a,&b)!=EOF)
        {
            __int64 cnt = 1;
            for(i=0;i<s&&a>1;i++)
            {
                int k=0;
                while(a%p[i]==0)
                {
                    k++;
                    a=a/p[i];
                }
                if(k)
                cnt = (cnt*sum(p[i],k*b+1))%mod;
            }
            if (a > 1)//a为素数
            cnt = (cnt*sum(a,b+1))%mod;
            printf("%I64d\n",cnt);
        }
        return 0;
    }

     

  • 相关阅读:
    设计模式:迭代器模式
    设计模式:观察者模式
    设计模式:解释器模式
    设计模式:策略模式
    设计模式:状态模式
    设计模式:代理模式
    strtok函数
    人们眼中的程序员
    如何用C语言获取文件的大小
    C++著名库的比较和学习经验
  • 原文地址:https://www.cnblogs.com/misty1/p/2480888.html
Copyright © 2011-2022 走看看