hdu-4990 Reading comprehension(快速幂+乘法逆元)

题目链接:

Reading comprehension

Time Limit: 2000/1000 MS (Java/Others)   

 Memory Limit: 32768/32768 K (Java/Others)

Problem Description
 
Read the program below carefully then answer the question.
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include<iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include<vector>

const int MAX=100000*2;
const int INF=1e9;

int main()
{
  int n,m,ans,i;
  while(scanf("%d%d",&n,&m)!=EOF)
  {
    ans=0;
    for(i=1;i<=n;i++)
    {
      if(i&1)ans=(ans*2+1)%m;
      else ans=ans*2%m;
    }
    printf("%d\n",ans);
  }
  return 0;
}
 

 

Input
 
Multi test cases,each line will contain two integers n and m. Process to end of file.
[Technical Specification]
1<=n, m <= 1000000000
 

 

Output
 
For each case,output an integer,represents the output of above program.
 

 

Sample Input
1 10
3 100
 

 

Sample Output
1
5
 
题意:
 
给n和m,问如果按给的程序执行,最后得结果是多少;
 
思路:
 
把给的程序编程通项公式可以发现:
当n为奇数时ans=(2^(n+1)-1)/3%m;
当n为偶数时ans=(2^(n+1)-2)/3%m;
这个可以用二项式公式得到;2^0+2^1+2^2+...+2^(n-1)=2^n-1;然后啦啦啦啦就出来了;
可是这个取模有除法诶,除法的我不会怎么办,所以就去看了求乘法逆元怎么求,然后没看懂,但我看懂了这个式子:
 
ans=a/b%m  <==>ans=a%(b*m)/b;
 
证明如下:
 
a/b=km+x;
a=kbm+bx;
a%(b*m)=bx;
a%(b*m)/b=x;
a/b%m=x=a%(b*m)/b;
前提是a能整除b,即b|a;
然后一个快速幂就搞出结果啦啦啦;
 
 
 
AC代码:
/*Accepted    4990    0MS    1568K    518 B    G++    2014300227*/
#include <bits/stdc++.h>
using namespace std;
const int N=3e5+4;
typedef long long ll;
int n,m;
ll fastpow(int x,int y)
{
    int temp=x;
    ll mod=3*(ll)y;
    ll ans=1,base=2;
    while(x)
    {
        if(x&1)ans=(ans*base%mod);
        base=base*base%mod;
        x=(x>>1);
    }
    if(temp%2==0)return (ans-1%mod+mod)%mod;
    else return (ans-2%mod+mod)%mod;
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        printf("%lld\n",fastpow(n+1,m)/3);
    }

    return 0;
}

 

 
posted @ 2016-04-16 12:11  LittlePointer  阅读(599)  评论(0编辑  收藏  举报