HDU 1452 Happy 2004

13 篇文章 0 订阅

2004 = 2^2*3*167

2004^x = 2^2*x*3^x*167^x

sum(x) 表示 x 的因子和则有 sum(2004^x) %29 = (2^2*x)%29*(3^x)%29*(167^x)%29

∵ 167 % 29 = 22

∴ sum(2004^x)%29 = (2^2*x)%29*(3^x)%29*(22^x)%29

                                      =sum(2^2*x)%29*sum(3^x)%29*sum(22^x)%29

又已知 若p为素数 sum(p^n) = 1+p+p^2+...+p^n = (p^(n+1)-1) /(p-1) (等比数列求和)

∴ 设 a = sum(2^2*x)%29

          b = sum(3^x)%29

          c = sum(22^x)%29

由上述式子可得 

          a = (2^(2*x+1)-1)%29

          b = (3^(x+1)-1)/2%29

          c = (22^(x+1)-1)/21 %29

又有 模运算法则  乘法法则 (a*b)%MOD = (a%MOD*b%MOD)%MOD

                               除法法则 (a/b)%MOD = (a*b^(-1)%MOD) 

∴ sum(2004^x)%29 = (2^(2*x+1)-1)%29 * [(3^(x+1)-1)/2]%29*[(22^(x+1)-1)/21]%29

                                      = (2^(2*x+1)-1)%29 *[(3^(x+1)-1)*2^(-1)%29]*[(22^(x+1)-1)*21^(-1)%29]

     这里的 b^(-1) 是b的逆元素(%MOD)

     2的逆元是15       2*15 = 30%29 = 1

     21的逆元是18    21*18 = 378%29 = 1

     (即下面所说的inv    满足该条件   c*inv(c)%MOD = 1    最小的)

又∵ (a*b)/c%MOD = a%MOD*b%MOD*inv(c)

         c*inv(c)%MOD = 1 inv(c)是所有满足上式中最小的

         inv(2) = 15, inv(21) = 18

∴    sum(2004^x)%29 = ((2^(2*x+1)-1)*(3^(x+1)-1)*15*(22^(x+1)-1)*18)%29

                                     a  = (2^(2*x+1)-1)%29

                                     b  = (3^(x+1)-1)*15%29

                                     c  = (22^(x+1)-1)*18%29

       sum(2004^x)%29 = (a*b)%29*c%29

接下来用快速幂就可以解决咯啊~    

快速幂 传送门

#include <iostream>
#include <cstdlib>

using namespace std;
typedef long long LL;

LL quick_mod(LL a,LL b)
{
    LL ans = 1;
    while(b)
    {
        if(b&1) ans=ans*a%29;
        b>>=1;
        a=a*a%29;
    }
    return ans ;
}
int main()
{
    LL x,a,b,c;
    while(cin>>x&&x)
    {
        a = (quick_mod(2,2*x+1)-1)%29;
        b = (quick_mod(3,x+1)-1)*15%29;
        c = (quick_mod(22,x+1)-1)*18%29;
        cout<<(a*b)%29*c%29<<endl;
    }
    return 0;
}

研究了好长时间  找各路大牛的代码 又添加了些自己的理解才弄得差不多了这道题~


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值