数论

来源:互联网 发布:mac wine下载安装 编辑:程序博客网 时间:2024/06/05 15:21

Sumdiv
总时间限制: 1000ms 内存限制: 65536kB
描述
Consider two natural numbers A and B. Let S be the sum of all natural divisors of A^B. Determine S modulo 9901 (the rest of the division of S by 9901).
输入
The only line contains the two natural numbers A and B, (0 <= A,B <= 50000000)separated by blanks.
输出
The only line of the output will contain S modulo 9901.
样例输入
2 3
样例输出
15
提示
2^3 = 8.
The natural divisors of 8 are: 1,2,4,8. Their sum is 15.
15 modulo 9901 is 15 (that should be output).

概念:唯一分解后的数A的因子的和
和

根据这个公式,可以先将这个整数分解,然后根据下面这个求模运算的性质进行计算:
求模运算
以上为概念问题,接下来就是实现。

首先是O(logN)的等比数列求和,要用到递归。
当项数为偶数,即最高次项次数n为奇数时,可以根据提出公因式得到如下变形:
等比数列求和1
最终可变形为:
等比数列求和2
同理,当项数为奇数,即最高次项次数n为偶数时,可以得到如下变形:
等比数列求和3

其中,需要用到 a^b mod k 的O(logN)算法,直接使用递归即可,也可以用二进制法,本质上是一样的。最后,整道题的思路就是先分解A,再运用以上的公式求解即可。

参考代码

#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <stack>#include <queue>#include <map>#include <set>using std::cin;using std::cout;using std::endl;const int mod=9901;int A,B;struct factor{    int base;    int index;} factors[7100]; //sqrt(50000000)=7071int numOfFactor;int power(int base, int index){    if(index==0)    {        return 1;    }    int temp=power(base,index>>1);    long long ans=temp*temp%mod;    if(index&1)    {        ans=ans*base%mod;    }    return ans;}long long sum(int q, int n){    if(n==0)    {        return 1;    }    else if(n%2==1)    {        return (sum(q,n/2) * (1 + power(q,n/2+1))) % mod;    }    else    {        return (sum(q,n/2-1) * (1 + power(q,n/2+1)) + power(q,n/2)) % mod;    }}void resolve(){    int times=sqrt(A);    for(int i=2; i<=times; i++)    {        if(A%i==0)        {            factors[numOfFactor].base=i;            while(A%i==0)            {                factors[numOfFactor].index++;                A/=i;            }            numOfFactor++;        }    }    if(A!=1) //若A不为1,说明还有且仅有一个大于sqrt(A)的因数     {        factors[numOfFactor].base=A;        factors[numOfFactor].index=1;        numOfFactor++;    }}int main(){    scanf("%d%d",&A,&B);    resolve();    long long ans=1;    for(int i=0; i<numOfFactor; i++)    {        ans=(ans*sum(factors[i].base,factors[i].index*B))%mod; //注意是B次方,所以指数乘以B     }    printf("%d",(int)ans);    return 0;}
0 0
原创粉丝点击