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;
}
#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
[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; }