http://acm.pku.edu.cn/JudgeOnline/problem?id=1845
Sumdiv
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 2659 | Accepted: 461 |
Description
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).
Input
The only line contains the two natural numbers A and B, (0 <= A,B <= 50000000)separated by blanks.
Output
The only line of the output will contain S modulo 9901.
Sample Input
2 3
Sample Output
15
Hint
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).
The natural divisors of 8 are: 1,2,4,8. Their sum is 15.
15 modulo 9901 is 15 (that should be output).
Source
Romania OI 2002
思路很简单就是暴力,只要注意下中间过程取mod的时候
1.对a分解素数,得到pi,ci分别表示第i个素因子和它的个数
2.ci*b,就是a^b=p1^(c1*b) * .... * pi^(ci*b)
3.所求的就是ans=(1+p1+p1^2+...+p1^(c1*b))*()...*(1+pi+pi^2+...+pi^(ci*b))
4.由于b 比较大,所以求1+p1+p1^2+...+p1^(c1*b)的时候使用二分,要注意取mod,小心溢出
以下是参考代码
其中pow_mod就是a^b mod c的函数,这里不列出了
思路很简单就是暴力,只要注意下中间过程取mod的时候
1.对a分解素数,得到pi,ci分别表示第i个素因子和它的个数
2.ci*b,就是a^b=p1^(c1*b) * .... * pi^(ci*b)
3.所求的就是ans=(1+p1+p1^2+...+p1^(c1*b))*()...*(1+pi+pi^2+...+pi^(ci*b))
4.由于b 比较大,所以求1+p1+p1^2+...+p1^(c1*b)的时候使用二分,要注意取mod,小心溢出
以下是参考代码
- #include <iostream>
- using namespace std;
- typedef unsigned long long llong;
- int p[4000],len=0,top[32][2],tlen;
- bool s[7072]={true,true};
- void split(llong n)
- {
- tlen=0;
- int i;
- for(i=0;i<len;i++)
- {
- if(n%p[i]==0)
- {
- top[tlen][0]=0;
- top[tlen][1]=p[i];
- while(n%p[i]==0)
- {
- top[tlen][0]++;
- n/=p[i];
- }
- tlen++;
- if(n==1||(n<=7071&&!s[n]))break;
- }
- }
- if(n!=1){top[tlen][0]=1;top[tlen++][1]=n;}
- }
- llong sum(int n,llong k)
- {
- if(k==1)return 1;
- llong tmp=sum(n,k/2);
- if(k&0x1)
- return (tmp%9901+pow_mod(n,k/2,9901)+pow_mod(n,k/2+1,9901)*tmp)%9901;
- return (tmp%9901+pow_mod(n,k/2,9901)*tmp)%9901;
- }
- int main()
- {
- llong a,b,ans;
- int i,j;
- for(i=2;i<=84;i++)if(!s[i])for(j=i;j*i<=7071;j++)s[i*j]=true;
- for(i=2;i<=7071;i++)if(!s[i])p[len++]=i;
- while(cin>>a>>b)
- {
- ans=1;
- split(a);
- for(i=0;i<tlen;i++)
- {
- ans*=sum(top[i][1],top[i][0]*b+1);
- ans%=9901;
- }
- cout<<ans<<endl;
- }
- return 0;
- }