Sumdiv POJ 1845

http://poj.org/problem?id=1845

题目

Time Limit: 1000MS   Memory Limit: 30000K

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).

题解

筛素数后试除不行,因为空间限制

直接试除

得到了$1sim sqrt{A}$的素因子,可以肯定剩下的那个一定是素数,就像之前的Safe Upperbound一样

占坑= =

AC代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<set>
#include<cassert>

#define REP(r,x,y) for(register int r=(x); r<(y); r++)
#define REPE(r,x,y) for(register int r=(x); r<=(y); r++)
#ifdef sahdsg
#define DBG(...) printf(__VA_ARGS__)
#else
#define DBG(...) (void)0
#endif

using namespace std;
typedef long long LL;
typedef pair<LL, LL> pll;
typedef pair<int, int> pii;
#define MO 9901
#define MAXN 50000007
inline int qpow(int a, int b) {
	a%=MO;
	int ans=1;
	for(;b;b>>=1) {
		if(b&1) ans=(LL)ans*a%MO;
		a=(LL)a*a%MO;
	}
	return ans;
}
int sum(int a, int b) {
	if(a==0) return 0; if(b==0) return 1;
	if(b&1)  {
		return (LL)sum(a,b/2)*(1+qpow(a,b/2+1))%MO;
	} else {
		return ((LL)sum(a,b/2-1)*(1+qpow(a,b/2))%MO+qpow(a,b))%MO;
	}
}
int a,b;
int main() {
	scanf("%d%d", &a, &b);
	if(!a) {puts("0"); return 0;}
	LL ans=1;
	for(int i=2;i*i<=a;i++) {
		int cnt=0;
		if(!(a%i)) {
			a/=i, cnt++;
			while(!(a%i)) {
				a/=i,cnt++;
			}
			(ans*=sum(i,cnt*b))%=MO;
		}
	}
	if(a!=1) (ans*=sum(a,b))%=MO;
	printf("%lld
", ans);
	return 0;
}
原文地址:https://www.cnblogs.com/sahdsg/p/10645948.html