您的位置:首页 > 其它

poj1845 Sumdiv

2012-05-27 14:25 232 查看
题意:求A^B的值的所有因子的和模9901,例如2^3=8 => 1+2+4+8=15。最后答案为 15。

分析:先将A^B分解成素因数形式:A^B = (P1^k1) + (P2^k2) + (P3^k3) + ...

那么A^B所有因子之和就是:S = (1 + P1^1 + P1^2 + P1^3 +...+ P1^K) * (1 + P2^1 + P2^2 + P2^3+...+P2^K) * (1 + P3^1 + P3^2 + P3^3 +...+ P3^K) * (...

计算 1 + P + P^2 + P^3 +...+ P ^K 可用二分求解;

当k是偶数时:例如k=4,1 + P + P^2 + P^3 + P^4 = (1+P) + P^2 * (1+P*(1+P));

当k是奇数时:例如k=5,1 + P + P^2 + P^3 + P^4 + P^5 = (1 + P + P^2) + P^3 * (1 + P + P^2)

#include <iostream>
#include <fstream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <bitset>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <ctime>
#define LL long long
#define Vi vector<int>
#define Si set<int>
#define readf freopen("input.txt","r",stdin)
#define writef freopen("output.txt","w",stdout)
#define FU(i,a) for(int i(1); i <= (a); i++)
#define FD(i,a) for(int i(a); i >= (1); i--)
#define FOR(i,a,b) for(int i(a);i <= (b); i++)
#define FORD(i,a,b) for(int i(a);i >= (b); i--)
#define SET(a,b) memset(a,b,sizeof(a))
#define SD(a) scanf("%d",&(a))
#define LN printf("\n")
#define PS printf(" ")
#define pb push_back
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const double pi = acos(-1.0);
const int maxn = 10001;
const int INF=99999999;
using namespace std;
int A,B;
int M = 9901;
LL pow(LL a,LL exp){
LL ret=1,s=a%M;
while(exp){
if(exp&1)
ret=(ret*s)%M;
exp>>=1;
s=(s*s)%M;
}
return ret;
}
LL sum(LL p,LL n){//求1 + p + p^2 +...+ p^n;
if(n==0)
return 1;
if(n & 1) //n % 2 == 0;
return (((1 + pow(p,n/2+1)) % M) * (sum(p,n/2) % M)) % M;
else
return (((1 + pow(p,n/2+1)) % M) * (sum(p,(n-1)/2) % M) + pow(p,n/2) % M) % M;
}
int main(){
LL s, ans;
int i, p[maxn], c[maxn]; //p[i]表示第i个素因子,c[i]表示它的个数。
while(scanf("%d%d",&A,&B)!= EOF){
memset(p, 0, sizeof(p));
memset(c, 0, sizeof(c));
//a^b=p1^(c1*b) * .... * pi^(ci*b)
//ans=(1+p1+p1^2+...+p1^(c1*b))*()...*(1+pi+pi^2+...+pi^(ci*b))
//把A分解素数
for(i=2; i*i<=A; i++){//求所有A的素因子存在p[]中,
if(A % i ==0){
p[++p[0]] = i;
while( A % i == 0){
A /= i;
++c[p[0]]; //对应的素因子的个数。
}
}
}
if( A != 1){ //处理最后一个数。
p[++p[0]] = A;
c[p[0]] = 1;
}
ans = 1;
for(i=1; i<=p[0]; i++)//sum=(p1^(n1*B+1)–1)/(p1-1)*(p2^(n2*B+1)–1)/(p2–2)*…
ans = ((ans % M) * (sum(p[i], c[i]*B)) % M) % M;
printf("%lld\n",ans);

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: