POJ1845 数学
题意:求A^B的所有约数之和 Mod 9901。
思路:大数模运算。两个最基本公式:(A*B)%C = ((A%C)*(B%C))%C 和 (A+B)%C = ((A%C)+(B%C))%C 。用__int64的原因为 n = cnt[i] * B (cnt[i]为A第i个素因子的个数)可能会超int。
1: 对A进行素因子分解得
A = p1^a1 * p2^a2 * p3^a3 *...* pn^an.
故 A^B = p1^(a1*B) * p2^(a2*B) *...* pn^(an*B);
2:A^B的所有约数之和为:
sum = [1+p1+p1^2+...+p1^(a1*B)] * [1+p2+p2^2+...+p2^(a2*B)] *...* [1+pn+pn^2+...+pn^(an*B)].
如 200 = 2^3 * 5^2 : sum(200) = [1 + 2 + 4 + 8] * [1 + 5 + 25].
3: 求等比数列1+pi+pi^2+pi^3+...+pi^n可以由递归形式的二分求得:(模运算不能用等比数列和公式!)
若n为奇数,一共有偶数项,则:
1 + p + p^2 + p^3 +...+ p^n
= (1+p^(n/2+1)) + p * (1+p^(n/2+1)) +...+ p^(n/2) * (1+p^(n/2+1))
= (1 + p + p^2 +...+ p^(n/2)) * (1 + p^(n/2+1))
如:1 + p + p^2 + p^3 + p^4 + p^5 = (1 + p + p^2) * (1 + p^3)
若n为偶数,一共有奇数项,则:
1 + p + p^2 + p^3 +...+ p^n
= (1+p^(n/2+1)) + p * (1+p^(n/2+1)) +...+ p^(n/2-1) * (1+p^(n/2+1)) + p^(n/2)
= (1 + p + p^2 +...+ p^(n/2-1)) * (1+p^(n/2+1)) + p^(n/2);
如:1 + p + p^2 + p^3 + p^4 = (1 + p) * (1 + p^3) + p^2
#include<cstdio> #include<iostream> #include<cstdlib> #include<algorithm> #include<cmath> #include<string> #include<cstring> #include<set> #include<map> #include<list> #include<queue> #include<vector> #define tree int o,int l,int r #define lson o<<1,l,mid #define rson o<<1|1,mid+1,r #define lo o<<1 #define ro o<<1|1 #define Uint unsigned int #define UI unsigned int #define inf 0x7fffffff #define eps 1e-7 #define N 109 #define M 9901 using namespace std; int T,n,m,k,t; int p[N]; int num[N]; int dfs(int ep,int k,int &d) { if(k==1) { d=ep; return 1; } int dd; int he=dfs(ep,k>>1,dd); if(k%2==0) { he=(he+he*dd)%M; d=(dd*dd)%M; return he; } else { d=dd; dd=(dd*ep)%M; he=(he+he*dd+d)%M; d=(dd*d)%M; return he; } } int main() { #ifndef ONLINE_JUDGE freopen("ex.in","r",stdin); #endif int cnt=0; int a,b; while (scanf("%d%d",&a,&b)==2) { memset(num,0,sizeof(num)); int x=a; cnt=0; for(int i=2; i<=x&&x>1; i++) if(x%i==0)//x%i==0则i一定是质数 { p[cnt]=i; while(x%i==0) { num[cnt]++; x/=i; } cnt++; } for (int i=0; i<cnt; ++i ) { num[i]=(num[i]*b+1); } int ans=1; for (int i=0; i<cnt; ++i ) { int te; int he=dfs(p[i]%M,num[i],te); ans=(ans*he)%M; } printf("%d\n",ans); } return 0; }