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

时间:2023-11-20 18:32:08

题目链接:

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+;
typedef long long ll;
int n,m;
ll fastpow(int x,int y)
{
int temp=x;
ll mod=*(ll)y;
ll ans=,base=;
while(x)
{
if(x&)ans=(ans*base%mod);
base=base*base%mod;
x=(x>>);
}
if(temp%==)return (ans-%mod+mod)%mod;
else return (ans-%mod+mod)%mod;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
printf("%lld\n",fastpow(n+,m)/);
} return ;
}