zoukankan      html  css  js  c++  java
  • 二分求幂——hdu1852

    // 这题主要求S
    // 结论: S = (251^(n+1)-1) * (2^(3n+1)-1) / 250 
    // 是两个等比数列和相乘 
    // 
    // 推理:
    // 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
    // 因为S有个分母250, 设 S = X/250
    // 则S%K = (X/250)%K = (X%(250*K))/250
    // 变成先求余数再除法的形式

    View Code
    #include <stdio.h>

    // 求 (x^exp)%p 的值 O(LOG(exp))
    int ExpMod(int x, int exp, int p)
    {
    if( exp==0 )
    {
    return 1;
    }
    __int64 ret
    = ExpMod(x, exp>>1, p);
    ret
    = (ret*ret)%p;
    if( exp & 1 ) {
    ret
    = (ret*x)%p;
    }
    return (int)ret;
    }

    int main()
    {
    int n,k;
    while( scanf("%d %d", &n, &k), n&&k )
    {
    __int64 m
    =ExpMod(2,3*n+1,250*k);
    m
    =(m+250*k-1)%(250*k);

    __int64 m1
    =ExpMod(251,n+1,250*k);
    m1
    =(m1+250*k-1)%(250*k);

    m
    =(m*m1)%(250*k);
    m
    =m/250;

    printf(
    "%d\n",ExpMod(2008,m,k));
    }
    return 0;
    }

  • 相关阅读:
    Bootstrap学习笔记
    鼠标画矩形openCV
    开关openCV
    openCV图像形态学
    Android自定义ListView的Item无法响应OnItemClick的解决办法
    0-1背包问题
    java实现矩阵连乘的动态规划
    java 实现排序
    微信小程序--箭头表达式
    微信小程序--navigator url 跳转失效
  • 原文地址:https://www.cnblogs.com/huhuuu/p/2015239.html
Copyright © 2011-2022 走看看