现在的位置: 首页 > 综合 > 正文

poj1845 Sumdiv

2018年04月23日 ⁄ 综合 ⁄ 共 1916字 ⁄ 字号 评论关闭

题意:求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;
}




抱歉!评论已关闭.