题意:给你n和k,2008的n次方对k取余为m,求2008的m次方对k取余
推理:
2008 = 2^3 * 251
所以 2008^N 有 3N 个 2 和 N 个251
所有仅由2组成的因子有
2^0 2^1 2^2 ... 2^(3N)
设集合 C = {2^0, 2^1, 2^2 ...,2^(3N)};
SUM(C) = 2^(3n+1)-1
跟251组合产生的因子有
251^0 * C
251^1 * C
...
251^N * C
所有因子和为:
S = (251^(n+1)-1))/250 * (2^(3n+1)-1)
计算S%K:
S 很大, 不能保存在普通的数据类型中, 需要直接计算S%K,公式:x/d%k==x%(d*k)/d
因为S有个分母250, 设 S = X/250
则S%K = (X/250)%K = (X%(250*K))/250
变成先求余数再除法的形式
#include
#include
using namespace std;
typedef long long ll;
ll quckpow(ll a,ll b,ll mod){
ll ans = 1;
while(b){
if(b & 1) ans = a*ans %mod;
a = a*a % mod;
b = b >> 1;
}
return ans;
}
int main()
{
ll n,k;
while(scanf("%lld%lld",&n,&k) != EOF && n + k){
k = 250*k;
ll m = (quckpow(251,n+1,k)-1)%k * ((quckpow(2,3*n+1,k)-1)%k)%k;
m /= 250;
k /= 250;
ll ans = quckpow(2008,m,k);
printf("%lld\n",ans);
}
return 0;
}