第6部分 数学基础(提高篇)-->第1章 快速幂
1615:【例 1】序列的第 k 个数
时间限制: 1000 ms 内存限制: 524288 KB
【题目描述】
BSNY 在学等差数列和等比数列,当已知前三项时,就可以知道是等差数列还是等比数列。
现在给你序列的前三项,这个序列要么是等差序列,要么是等比序列,你能求出第 k 项的值吗。
如果第 k 项的值太大,对 200907 取模。
【输入】
第一行一个整数 T,表示有 T 组测试数据;
对于每组测试数据,输入前三项 a,b,c,然后输入 k。
【输出】
对于每组数据输出第 k 项的值,对 200907 取模。
【输入样例】
2
1 2 3 5
1 2 4 5
【输出样例】
5
16
【提示】样例说明:第一组是等差序列,第二组是等比数列。
数据范围与提示:对于全部数据,1≤T≤100,1≤a≤b≤c≤1e9,1≤k≤1e9 。
- 参考程序
#include<cstdio>
typedef long long ll;
ll mod=200907;
ll fastpow(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 t,a,b,c,k,ans; scanf("%lld",&t);
while(t--){
scanf("%lld%lld%lld%lld",&a,&b,&c,&k);
if(b-a==c-b){
ll d = b-a;
ans = (a+(k-1)*d)%mod;
}else{
ll q = b/a;
ans = a*fastpow(q, k-1)%mod;
}
printf("%lld\n",ans);
}
return 0;
}
1616:A 的 B 次方
时间限制: 1000 ms 内存限制: 524288 KB
【题目描述】给出三个整数 a,b,m,求 a^b mod m 的值。
【输入】一行三个整数 a,b,m。
【输出】一个整数,表示 a^b mod m 的值。
【输入样例】2 100 1007
【输出样例】169
【提示】数据范围与提示:对于全部数据,1≤a,b,m≤109 。
- 参考程序
#include<cstdio>
typedef long long ll;
ll pow(ll a,ll b,ll m){
ll ans=1;
while(b){
if(b&1) ans=(ans*a)%m;
b >>= 1;
a = (a*a)%m;
}
return ans;
}
int main(){
int a,b,m; scanf("%d%d%d",&a,&b,&m);
printf("%lld\n",pow(a,b,m));
return 0;
}
1617:转圈游戏
时间限制: 1000 ms 内存限制: 524288 KB
【题目描述】
n 个小伙伴(编号从 0 到 n-1)围坐一圈玩游戏。
按照顺时针方向给 n 个位置编号,从 0 到 n-1。
最初,第 0 号小伙伴在第 0 号位置,第 1 号小伙伴在第 1 号位置,……,依此类推。
游戏规则如下:
每一轮第 0 号位置上的小伙伴顺时针走到第 m 号位置,
第 1 号位置小伙伴走到第 m+1 号位置,……,依此类推,
第 n-m 号位置上的小伙伴走到第 0 号位置,
第 n-m+1 号位置上的小伙伴走到第 1 号位置,……,
第 n-1 号位置上的小伙伴顺时针走到第 m-1 号位置。
现在,一共进行了 10^k 轮,请问 x 号小伙伴最后走到了第几号位置。
【输入】输入共 1 行,包含 4 个整数 n、m、k、x,每两个整数之间用一个空格隔开。
【输出】输出共 1 行,包含 1 个整数,表示 10k 轮后 x 号小伙伴所在的位置编号。
【输入样例】10 3 4 5
【输出样例】5
【提示】数据范围与提示:
对于 30% 的数据,0<k<7;
对于 80% 的数据,0<k<1e7 ;
对于 100% 的数据,1<n<1e6,0<m<n,1≤x≤n,0<k<1e9。
- 参考程序
#include<cstdio>
typedef long long ll;
int n,m,k,x;
ll pow(ll a,ll b){
ll ans=1;
while(b){
if(b&1) ans=(ans*a)%n;
b >>= 1;
a = (a*a)%n;
}
return ans;
}
int main(){
scanf("%d%d%d%d",&n,&m,&k,&x);
printf("%lld\n",(x+m*pow(10,k))%n);
return 0;
}
1618:越狱
时间限制: 1000 ms 内存限制: 524288 KB
【题目描述】
原题来自:HNOI 2008
监狱有连续编号为 1 到 n 的 n 个房间,每个房间关押一个犯人。
有 m 种宗教,每个犯人可能信仰其中一种。
如果相邻房间的犯人信仰的宗教相同,就可能发生越狱。
求有多少种状态可能发生越狱。
【输入】输入两个整数 m 和 n。
【输出】可能越狱的状态数,对 100003 取余。
【输入样例】2 3
【输出样例】6
【提示】样例说明
所有可能的 6 种状态为:{0,0,0},{0,0,1},{0,1,1},{1,0,0},{1,1,0},{1,1,1}。
数据范围与提示:对于全部数据,1≤m≤1e8,1≤n≤1e12 。
- 分析:越狱情况 = 总情况 - 不可越狱情况。
- 总情况:m^n。
- 不可越狱情况:如果当前犯人选择 1,下一位犯人可选择情况(m-1)种,依此类推,可得不可越狱情况有:m*(m-1)^(n-1)。
- 参考程序
#include<cstdio>
typedef long long ll;
ll n,m,mod=100003;
ll pow(ll a,ll b){
ll ans=1;
while(b){
if(b&1) ans=(ans*a)%mod;
b >>= 1;
a = (a*a)%mod;
}
return ans;
}
int main(){
scanf("%lld%lld",&m,&n);
if(n<2) printf("0\n");
else printf("%lld\n",((pow(m,n)-m*pow(m-1,n-1)%mod)+mod)%mod);
return 0;
}