hdu1852 Beijing2008

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\n",sum);  
    }
}
posted @ 2021-02-08 23:05  zx0710  阅读(22)  评论(0编辑  收藏  举报