[1]序列的第k个数
题目描述
BSNY 在学等差数列和等比数列,当已知前三项时,就可以知道是等差数列还是等比数列。现在给你序列的前三项,这个序列要么是等差序列,要么是等比序列,你能求出第 k 项的值吗。 如果第 k 项的值太大,对 200907 取模。
输入
第一行一个整数 T,表示有 T 组测试数据;
对于每组测试数据,输入前三项 a,b,c,然后输入 k。
对于全部数据,1<=T<=100,1<=a<=b<=c<=109,1<=k<=109
输出
对于每组数据输出第 k 项的值,对 200907 取模。
样例输入
2
1 2 3 5
1 2 4 5
样例输出
5
16
题目类型:
快速幂
思路:
按题意判断是不是等差数列,如果是的话就用等差数列通项公式求值,不是的话就是等比数列,用快速幂求值


#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#define ll long long
using namespace std;

int fpow(int a,int b,int n){
// if(b==0) return 1;
	if(b==1) return a;
	if(b%2 == 1){
		ll t = fpow(a,b/2,n);
		t = t * t % n;
		t = t * a % n;
		return t; 
	}
	else{
		ll t = fpow(a,b/2,n);
		t = t * t % n;
		return t;
	}
} 
int main(void)
{
	int t;
	cin>>t;
	while(t--){
		ll a,b,c,k,ans = 0;
		cin>>a>>b>>c>>k;
		if((b*2) == (a+c)){
			ans = a + ((k-1) % 200907)*((b-a) % 200907 )% 200907;
		}
		else {
			ans = fpow(b/a,k-1,200907) * a  % 200907;
		}
		printf("%d\n",ans);
	}
}


[2] A的B次方
题目描述
给出三个整数 a,b,m,求 abmodm 的值。
输入
一行三个整数 a,b,m。
对于全部数据,1≤a,b,m≤109。
输出
一个整数,表示 abmodm 的值。

样例输入
2 100 1007
样例输出
169
思路:
就是套快速幂的板子求解就可以了

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#define ll long long
using namespace std;

int fpow(int a,int b,int n){
// if(b==0) return 1;
	if(b==1) return a;
	if(b%2 == 1){
		ll t = fpow(a,b/2,n);
		t = t * t % n;
		t = t * a % n;
		return t; 
	}
	else{
		ll t = fpow(a,b/2,n);
		t = t * t % n;
		return t;
	}
} 
int main(void)
{
	ll a,b,m;
	cin>>a>>b>>m;
	ll ans = fpow(a,b,m);
	cout<<ans<<endl;
}

[3] 转圈游戏
题目描述
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 号位置。
现在,一共进行了 10k 轮,请问 x 号小伙伴最后走到了第几号位置。
输入
输入共 1 行,包含 4 个整数 n、m、k、x,每两个整数之间用一个空格隔开。
对于 30% 的数据,0<k<7;
对于 80% 的数据,0<k<107;
对于 100% 的数据,1<n<106,0<m<n,1≤x≤n,0<k<109。
输出
输出共 1 行,包含 1 个整数,表示 10k 轮后 x 号小伙伴所在的位置编号。
样例输入
10 3 4 5
样例输出
5
题型:
模拟,快速幂
思路:
读题之后可以退出所在的位置编号就是原来编号的值(X)加上变化值(M)乘以10k,注意一下取模就可以了


#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#define ll long long
using namespace std;

int fpow(int a,int b,int n){
// if(b==0) return 1;
	if(b==1) return a;
	if(b%2 == 1){
		ll t = fpow(a,b/2,n);
		t = t * t % n;
		t = t * a % n;
		return t; 
	}
	else{
		ll t = fpow(a,b/2,n);
		t = t * t % n;
		return t;
	}
} 
int main(void)
{
	ll n,m,k,x;
	cin>>n>>m>>k>>x;
	int ans = (x + fpow(10,k,n) * m  % n) % n;
	cout<<ans<<endl;
}


[4] 越狱
题目描述
监狱有连续编号为 1 到 n 的 n 个房间,每个房间关押一个犯人。有 m 种宗教,每个犯人可能信仰其中一种。如果相邻房间的犯人信仰的宗教相同,就可能发生越狱。求有多少种状态可能发生越狱。
输入
输入两个整数 m 和 n。

对于全部数据,1≤m≤108,1≤n≤1012。

输出
可能越狱的状态数,对 100003 取余。
样例输入
2 3
样例输出
6
思路:
借鉴童同学的想法,直接算越狱的状态很难,所以采用间接的方法,先算不会越狱的情况,再把总的情况剪掉不会越狱的情况剩下的数量就是越狱的数量.然后需要注意的是取模之后有可能再相减有可能会存在负数的情况,只要再加上一个mod就不会了,还要注意n,m的范围

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#define ll long long
using namespace std;

ll fpow(ll a,ll b,ll n){
// if(b==0) return 1;
	if(b==1) return a;
	if(b%2 == 1){
		ll t = fpow(a,b/2,n);
		t = t * t % n;
		t = t * a % n;
		return t; 
	}
	else{
		ll t = fpow(a,b/2,n);
		t = t * t % n;
		return t;
	}
} 
int main(void)
{
	ll n,m;
	int md = 100003;
	cin>>m>>n;
	ll tot = fpow(m,n,md) % md;
	ll may = m * fpow(m-1,n-1,md) % md;
	ll ans = (tot - may + md) % md;
	cout<<ans<<endl;
// cout<<(fpow(m,n,md)%md - (fpow(m-1,n-1,md)*m) %md +md)%md<<endl;
}