设为首页 加入收藏

TOP

HDU 1852 快速求幂
2013-02-08 14:29:54 】 浏览:430
Tags:HDU  1852  快速

  题目wa了好多回悲催…不能直接求逆元来计算,还是要用到数论中的小技巧啊…

  贴神牛的题解吧

  // 这题主要求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

  // 变成先求余数再除法的形式

  知道了数论中的技巧,不能用你逆元来求哇,因为不满足gcd(250,k )或者gcd(2,k)不一定是互质的, 代码就不是再是问题了,

  #include<stdio.h>

  int mult(int a1,int n,int k){

  if(n==0) return 1;

  __int64 b=1,a = a1;

  while(n>1){

  if(n%2==0) {

  a=a*a%k;

  n/=2;

  }

  else {

  b=b*a%k;

  n--;

  }

  }

  return a*b%k;

  }

  int main(){

  int n,k;

  while(scanf("%d%d",&n,&k),n&&k){

  __int64 a=mult(2,3*n+1,250*k);

  __int64 b=mult(251,n+1,250*k);

  a-- , b--;

  a = ( a*b )%(250*k);

  a /= 250;

  printf("%d\n",mult(2008,a,k));

  }

  }

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇区间覆盖最小代价 下一篇TYVJ P2067(质因数分解)

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目