信息学奥赛一本通 提高篇 提高版 第六部分 数学基础 第1章 快速幂
#10193 「一本通 6.1 例 1」序列的第 k 个数
//#10193. 「一本通 6.1 例 1」序列的第 k 个数
//在线测评地址https://loj.ac/problem/10193
//样例通过,提交AC。2018-9-25 23:09
#include
#define LL long long
#define mod 200907
LL quickPow(LL b,LL n){
LL ans=1;
while(n){
if(n&1)ans=(ans*b)%mod;
b=(b*b)%mod;
n>>=1;
}
return ans;//漏了此句
}
int main(){
LL T;
scanf("%lld",&T);
while(T--){
LL a,b,c,k;
scanf("%lld%lld%lld%lld",&a,&b,&c,&k);
if(b-a==c-b){//等差数列 a(n)=a(1)+(n-1)d
printf("%lld\n",(a%mod+(k-1)%mod*(b-a)%mod)%mod);
}else{//等比数列 a(n)=a(1)q^(n-1)
printf("%lld\n",a%mod*quickPow(b/a,k-1)%mod);//此处写成 printf("%lld\n",a%mod*quickPow(b/a,k)%mod);
}
}
return 0;
}
#10194 「一本通 6.1 练习 1」A 的 B 次方
//#10194. 「一本通 6.1 练习 1」A 的 B 次方
//在线测评地址https://loj.ac/problem/10194
//样例通过,提交AC。此题,属于 快速幂 模板 题。2018-9-26
#include
#define LL long long
LL quickPow(LL a,LL b,LL m){
LL ans=1;
while(b){
if(b&1)ans=(ans*a)%m;
a=(a*a)%m;
b>>=1;
}
return ans;
}
int main(){
LL a,b,m;
scanf("%lld%lld%lld",&a,&b,&m);
printf("%lld\n",quickPow(a,b,m));
return 0;
}
#10195 「一本通 6.1 练习 2」转圈游戏
//#10195. 「一本通 6.1 练习 2」转圈游戏
//在线测评地址https://loj.ac/problem/2608
//提交AC。2018-9-26
//P1965 转圈游戏
//在线测评地址https://www.luogu.org/problemnew/show/P1965
//动笔,模拟,举个比样例更简单的例子,发现如下规律
//x1=(x0+m)%n
//x2=(x1+m)%n?? => x2=(x0+2m)%n
//x3=(x3+m)%n?? => x3=(x0+3m)%n
//xq=(x0+qm)%n? => xq=(x0+qm%n)%n?? => xq=(x0+q%n*m)%q
//q=10^k??? 10^109 采用 快速幂 算法的时间复杂度 log(10^10^9) 大致 10^9 还是有些险
//快速幂,稳妥起见,不采用int 采用long long
//样例通过,一次成功,提交AC。2018-9-21
#include
#define LL long long
LL quickPower(LL a,LL b,LL p){
LL ans=1;
while(b){
if(b&1)ans=(ans*a)%p;
a=(a*a)%p;
b>>=1;
}
return ans;
}
int main(){
LL n,m,k,x,ans;
scanf("%lld%lld%lld%lld",&n,&m,&k,&x);//此处写成 scanf("%d%d%d%d",&n,&m,&k,&x);
ans=quickPower(10,k,n);
ans=(x+ans*m)%n;
printf("%lld\n",ans);
return 0;
}
#10196 「一本通 6.1 练习 3」越狱
//【HNOI 2008】 越狱
//#10196. 「一本通 6.1 练习 3」越狱
//https://loj.ac/problem/10196
//看了几遍题目,动手模拟了一遍,没有头绪。
//此文写得不错https://blog.csdn.net/even_bao/article/details/80160545
//摘抄如下:
//显然,越狱情况数 = 总情况数 - 不能越狱的情况数
//很容易发现,总情况数 = M^N
//不能越狱的情况数怎么求呢? 我们发现,不能越狱的情况,
//其实就是第一个人任选一种宗教,后面n-1个人,每个人都选一种与前面一个人不同的宗教,
//所以第一个人有M种选法,后N-1个人,每个人都有M-1种选法,因此,不能越狱的情况
//数 = M * (M - 1)^(N - 1)
//所以,越狱情况数 = M ^ N - M * (M - 1)^(N - 1)
//注意算乘方时,要用到快速幂
//上述方法,就是容次原理,该题难在数学推导,注意,是组合数学,编程不难。2018-9-26
//样例通过,提交AC。
#include
#define LL long long
#define mod 100003
LL quickPow(LL a,LL b){
LL ans=1;
while(b){
if(b&1)ans=(ans*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return ans;
}
int main(){
LL m,n,I,B,A;
scanf("%lld%lld",&m,&n);
I=quickPow(m,n);
B=m*quickPow(m-1,n-1)%mod;
A=(I-B+mod)%mod;//此处要注意,可能出现 负数,故要+mod。
printf("%lld\n",A);
return 0;
}
2018-9-26 AC 该节内容。