Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 17287 | Accepted: 4343 |
Description
Input
Output
Sample Input
2 3
Sample Output
15
Hint
2^3 = 8.15 modulo 9901 is 15 (that should be output).
题意:求出A^B的因子和
思路:根据唯一分解定理得A=p1^k1*p2^k2*...*pn^kn,所以说A^B=p1^(k1*B)*p2^(k2*B)*...*pn^(kn*B),所以说根据因子和公式得(1+p1+p1^2+...+p1^(k1*B))*(1+p2+p2^2+...+p2^(k2*B))*...*(1+pn+pn^2+...+pn^(kn*B)),结果就是一个个等比数列的乘积,但是数据是5e8,这样直接按照等比数列的求和公式写会超时或者RE,所以说要优化等比数列求和,用折半二分递归的方法求等比数列的和,这里就先不说了,等后来总结的时候再深究。
ac代码:
#include<stdio.h> #include<math.h> #include<string.h> #include<stack> #include<set> #include<queue> #include<vector> #include<iostream> #include<algorithm> #define MAXN 100010 #define LL long long #define ll __int64 #define INF 0x7fffffff #define mem(x) memset(x,0,sizeof(x)) #define PI acos(-1) #define eps 1e-10 using namespace std; int gcd(int a,int b){return b?gcd(b,a%b):a;} int lcm(int a,int b){return a/gcd(a,b)*b;} LL powmod(LL a,LL b,LL MOD){LL ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;} //head struct s { int num; int cnt; }p[MAXN]; int fun(int a,int n,int MOD) { if(n==0) return 1; if(n%2) return ((1+powmod(a,n/2+1,MOD))%MOD*fun(a,n/2,MOD)%MOD)%MOD; else return (powmod(a,n/2,MOD)+(1+powmod(a,n/2+1,MOD))%MOD*fun(a,(n-1)/2,MOD)%MOD)%MOD; } int main() { int a,b,i; while(scanf("%d%d",&a,&b)!=EOF) { int x=a; int ccnt=0; for(i=2;i*i<=x;i++) { if(x%i==0) { p[ccnt].num=i; int t=0; while(x%i==0) x/=i,t++; p[ccnt++].cnt=t; } if(x==1) break; } if(x!=1) { p[ccnt].num=x; p[ccnt].cnt=1; ccnt++; } LL ans=1; for(i=0;i<ccnt;i++) ans=(ans*fun(p[i].num,p[i].cnt*b,9901))%9901; printf("%d\n",ans); } return 0; }