poj1845 Sumdiv

将a质因数分解 S=p1^c1*b+p2^c2*b+...+pn^cn*b

根据乘法分配率可知答案=(p1^0+p1^1...+p1^c1*b)*(p2^0+p2^1...+p2^c2*b)*...*(pn^0+pn^1...+pn^cn*b)

1.如何快速求等比数列呢?我知道通项公式!S=(p^(c+1)-1)/(p-1)% 9901   除法部分乘逆元就是了pow(p-1,9901-2)

2.我不会逆元!   那就分治!  大概思想就是求一半数,通过乘某个数来求另一半,毕竟等比数列很特殊。

法二:

#include<cstdio>
#include<iostream>
#include<vector>
using namespace std;
const int MOD=9901;
typedef pair<int,int> P;
vector<P>v;
int power(int a,int b){
    int ret=1;
    for(;b;b>>=1){
        if(b&1)ret=ret*a%MOD;
        a=a*a%MOD;
    }
    return ret;
}
int sum(int p,int c){
    if(c==0)return 1;
    if(c%2)return (1+power(p,(c+1)/2))*sum(p,(c-1)/2)%MOD;
    else return ((1+power(p,c/2+1))*sum(p,(c-1)/2)+power(p,c/2))%MOD;
}
int main(){
    int a,b;
    scanf("%d%d",&a,&b);
    int ta=a;
    for(int i=2;i*i<=ta;++i){
        int cnt=0;
        while(a%i==0)a/=i,++cnt;
        v.push_back(P(i,cnt*b));
    }
    if(a!=1)v.push_back(P(a%MOD,b));
    int ans=1;
    for(int i=0;i<v.size();++i){
        cout<<v[i].first<<" "<<v[i].second<<endl;
        printf("%d
",sum(v[i].first%MOD,v[i].second)%MOD);
        ans=ans*sum(v[i].first%MOD,v[i].second)%MOD;
    }
    printf("%d",ans);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/Dream-Runner/p/10128791.html