hdu1852 Beijing2008
非常好的题目,题解见注释。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,k;
#define debug(x) cout<<#x<<':'<<x<<endl;
ll qpow(ll a,ll n,ll mod){
ll sum=1;
while(n){
if(n&1) sum=sum*a%mod;
a=a*a%mod;
n>>=1;
}
return sum;
}
/*
题意:求S=2008^n的所有因子数之和
M=S%K
输出2008^M%k
2008=2^3*251 的因子和,3n个2,n个251
2^0+2^1+2^2+...2^(3n)
251*(2^0+2^1+2^2+...2^(3n))
251^2*(2^0+2^1+2^2+...2^(3n))
......
S=(251^(n+1)-1)*(2^(3n+1)-1)/(250)
乘法逆元要求互质,所以这里的250很难处理
设S%K=(X/250)%K=(X%(250*K))/250<K//先取模再除
prvove.由公式 a=b(mod m) <=> aK=bK (mod mK)
所以 (X/250)=S(mod K) <=> X=S*250(mod 250K)
所以 S%K=(X%(250*K))/250
(251^(n+1)-1)
有公式(1+q)^(n+1)-1=q[1+(1+q)+(1+q)^2+(1+q)^3+...+(1+9)^n]
所以X%250==0;
对(250*K)取模之后依然能整除250的原因: 设b=x%K,250x%(250K)=250b,250x%(250K)/250=b因为b是整数所以整除
综上 ,M=(qpow(251,n+1,250K)-1)%(250K)
*qpow(2,3*n+1,250K)%(250K)
/250
*/
int main(){
while(~scanf("%lld%lld",&n,&k)){
if(n==0&&k==0) continue;
ll a=qpow(251,n+1,250*k)-1,b=qpow(2,3*n+1,250*k)-1,c=a*b%(250*k)/250;
ll sum=qpow(2008,c,k);
printf("%lld
",sum);
}
}