题目地址 -> 一个方法,因为mod捕食不是质数。
poj 1845 -> 两个方法都可以 还有一个求逆元的解法参考以前博客
先化等比数列: 设 sum = (1+q+…+qc)
假设 c为奇数, 则可以得到 sum = (1+q+…+q(c/2)+q((c+1)/2)+…+qc)
则为sum = (1+q+…+q(c/2)+q((c+1)/2)*(1+q+…+q(c/2)))
sum = (1+q((c+1)/2)) * (1+q+…+q(c/2))
当 c 为偶数时,同理, sum = (1+q+…+q(c/2-1)+q(c/2)+…+qc)
则为sum = (1+q+…+q(c/2-1)+q(c/2) *(1+q+…+q(c/2))+qc)
sum = (1+q(c/2)) * (1+q+…+q(c/2-1))+qc
现在就可以递归求等比数列的和。
考虑A,可以将它分解为p1c1 * p2c2 * … -> AB 为 p1Bc1 * p2Bc2 * …
所以它的约数之和为(1+p1,+…+pBc1)* (…) ……
每一个括号里面的都是一个等比数列。
代码1:
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const double eps = 1e-5;
const int mod = 2013;
const int N = 20;
int p[N],c[N],ans,cnt;
void init(){
cnt = 0;
memset(p,0,sizeof(p));
memset(c,0,sizeof(c));
ans = 1;
}
void divied(int x){
for(int i=2;i<=x/i;i++){
if(x % i == 0){
p[++cnt] = i;
while(x % i == 0) c[cnt]++,x /= i;
}
}
if(x > 1) p[++cnt]=x,c[cnt]=1;
}
int qmi(int a,int b){
int res = 1;
while(b){
if(b & 1) res = res*a%mod;
a = a*a%mod;
b >>= 1;
}
return res;
}
int sum_q(int p,int c){
if(c == 0) return 1;
if(c % 2) return (1+qmi(p,(c+1)/2))%mod*sum_q(p,c/2)%mod;
return ((1+qmi(p,c/2))%mod*sum_q(p,c/2-1)%mod+qmi(p,c))%mod;
}
signed main(){
IOS
#ifdef ddgo
freopen("C:\\Users\\asus\\Desktop\\ddgoin.txt","r",stdin);
#endif
int a,b;
while(cin>>a>>b){
if(!a && !b) break;
init();
divied(a);
for(int i=1;i<=cnt;i++) ans = ans*sum_q(p[i],b*c[i]) % mod;
cout<<ans<<endl;
}
return 0;
}
代码2: poj 1845
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//#include<bits/stdc++.h>
#include <iostream>
#include <stdio.h>
#define int long long
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const double eps = 1e-5;
const int mod = 9901;
const int N = 20;
int ans=1,cnt = 0;
int pp[N],c[N];
void divied(int x){
for(int i=2;i<=x/i;i++){
if(x % i == 0){
pp[++cnt] = i;
while(x % i == 0) c[cnt]++,x /= i;
}
}
if(x > 1) pp[++cnt]=x,c[cnt]=1;
}
int qmi(int a,int b){
int res = 1;
while(b){
if(b & 1) res = res*a%mod;
a = a*a%mod;
b >>= 1;
}
return res;
}
int sum_q(int p,int c){
if(c == 0) return 1;
else if(c % 2) return (1+qmi(p,(c+1)/2))*sum_q(p,c/2)%mod;
else return ((ll)(1+qmi(p,c/2))*sum_q(p,c/2-1)%mod+qmi(p,c))%mod;
}
signed main(){
IOS
#ifdef ddgo
freopen("C:\\Users\\asus\\Desktop\\ddgoin.txt","r",stdin);
#endif
int a,b; cin>>a>>b;
divied(a);
for(int i=1;i<=cnt;i++) ans = ans*sum_q(pp[i],b*c[i]) % mod;
cout<<ans<<endl;
return 0;
}