【信息学奥赛一本通】Part6.1 数学基础-快速幂

题目链接

A:序列的第k个数

输入描述:BSNY在学等差数列和等比数列,当已知前三项时,就可以知道是等差数列还是等比数列。现在给你序列的前三项,这个序列要么是等差序列,要么是等比序列,你能求出第k项的值吗。如果第k项的值太大,对200907取模。

第一行一个整数T,表示有T组测试数据;对于每组测试数据,输入前三项a,b,c,然后输入k。

输出描述:

对于每组数据输出第k项的值,对200907取模。

示例1

输入

2
1 2 3 5
1 2 4 5

输出

5
16

说明

第一组是等差序列,第二组是等比数列。

备注:

对于全部数据,1≤T≤100,1≤a≤b≤c≤109,1≤k≤1091 \leq T \leq 100,1 \leq a \leq b \leq c \leq 10^9,1 \leq k \leq 10^91≤T≤100,1≤a≤b≤c≤109,1≤k≤109。

解题思路:根据等差和等比数列的性质求解即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll ksm(ll a,ll b,ll p){
    ll res=1;
    while(b){
        if(b&1) res=res*a%p;
        a=a*a%p;
        b>>=1;
    }
    return res;
}
int main(){
    int t;
    cin>>t;
    while(t--){
        ll p=200907;
        ll a,b,c,k;
        cin>>a>>b>>c>>k;
        if(a+c==2*b) cout<<(a+(b-a)*(k-1))%p<<endl;
        else cout<<a*ksm(b/a,k-1,p)%p<<endl;
    }

    return 0;
}

B:A的B次方

 

题目描述

给出三个整数a,b,m,求ab?mod?ma^b \bmod mabmodm的值。

输入描述:

一行三个整数a,b,m。

输出描述:

一个整数,表示ab?mod?ma^b \bmod mabmodm的值。

示例1

输入

2 100 1007

输出

169

备注:

对于全部数据,1≤a,b,m≤1091 \leq a,b,m \leq10^91≤a,b,m≤109。

解题思路:扔个板子 结束

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll ksm(ll a,ll b,ll p){
    ll res=1;
    while(b){
        if(b&1) res=res*a%p;
        a=a*a%p;
        b>>=1;
    }
    return res;
}
int main(){
    ll a,b,m;
    cin>>a>>b>>m;
    cout<<ksm(a,b,m)<<endl;
    return 0;
}

C:转圈游戏

题目描述

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号位置。
现在,一共进行了10k10^k10k轮,请问x号小伙伴最后走到了第几号位置。

输入描述:

输入共1行,包含4个整数n、m、k、x,每两个整数之间用一个空格隔开。

输出描述:

输出共1行,包含1个整数,表示10k10^k10k轮后x号小伙伴所在的位置编号。

示例1

输入

10 3 4 5

输出

5

备注:

对于30%的数据,0 < k <7;对于80%的数据,0<k<1070 < k <10^70<k<107;对于100%的数据,1<n<1061< n < 10^61<n<106,0<m>,0<k<1090< k < 10^90<k<109。</m>

解题思路:规律:(x+m*ksm(10,k,n)%n)%n

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll ksm(ll a,ll b,ll p){
    ll res=1;
    while(b){
        if(b&1) res=res*a%p;
        a=a*a%p;
        b>>=1;
    }
    return res;
}
int main(){
    ll n,m,k,x;
    cin>>n>>m>>k>>x;
    cout<<(x+m*ksm(10,k,n)%n)%n<<endl;
    return 0;
}

D:越狱

题目描述

监狱有连续编号为1到n的n个房间,每个房间关押一个犯人。有m种宗教,每个犯人可能信仰其中一种。如果相邻房间的犯人信仰的宗教相同,就可能发生越狱。求有多少种状态可能发生越狱。

输入描述:

输入两个整数m和n。

输出描述:

可能越狱的状态数,对100003取余。

示例1

输入

2 3

输出

6

说明

所有可能的6种状态为:{0,0,0 }, {0,0,1 }, {0,1,1 }, {1,0,0 }, {1,1,0 }, {1,1,1 }。

备注:

对于全部数据,1≤m≤108,1≤n≤10121 \leq m \leq 10^8,1 \leq n \leq 10^{12}1≤m≤108,1≤n≤1012。解题思路:正难则反;总的可能-发生越狱的可能数

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll ksm(ll a,ll b,ll p){
    ll res=1;
    while(b){
        if(b&1) res=res*a%p;
        a=a*a%p;
        b>>=1;
    }
    return res;
}
int main(){
    ll m,n;
    ll p=100003;
    cin>>m>>n;
    cout<<((ksm(m,n,p)-m*ksm(m-1,n-1,p))%p+p)%p<<endl;
    return 0;
}

 

原文地址:https://www.cnblogs.com/Cutele/p/12242287.html

时间: 2024-10-05 05:04:43

【信息学奥赛一本通】Part6.1 数学基础-快速幂的相关文章

信息学奥赛一本通 提高篇 序列第k个数 及 快速幂

我是传送门 这个题首先是先判断是等差还是等比数列 等差的话非常简单: 前后两个数是等差的,举个栗子: 3 6 9 12 这几个数,(我感觉 1 2 3 4并说明不了什么) 每次都加3嘛,很容易看出,第一个数是3 * 1,第二个是3 * 2....以此类推 第k个数 = (第2个数 - 第1个数) * k ; (z - y) * k % 200907 % 200907 的原因是题目要求 但是这样并不能过 hack一下 4 7 10 13 用原先的公式:(7 - 4) * 4 % 200907 =

【信息学奥赛一本通】第三部分_栈 ex1_4cale (中缀转后缀7符号)

其实这个中缀转后缀是费了很大功夫的,明白算法后第一次实现花了近三小时ORZ #include <stdio.h> #include <string.h> #include <ctype.h> char Mstr[511],Msta[511] = {'@'},Bstr[511]; int sta[511]; const short list[4][4] = {{0,-1,1,1},{1,0,1,1},{1,1,1,-2},{-1,-1,2,1}}; int level (

信息学奥赛一本通 5.4 状态压缩动态规划

#loj 10170. 「一本通 5.4 例 1」骑士 看数据范围n<=10,所以不是搜索就是状压dp,又因为搜索会超时所以用dp dp[i][k][j]表示现已经放到第i行,前面共有k个,这一行状态为j so,dp[i][k][j]=dp[i-1][k-num[j]][t] #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cma

樱花(信息学奥赛一本通 1624)

[题目描述] 原题来自:HackerRank Equations 求不定方程: 1/x + 1/y = 1/n! 的正整数解 (x,y)的数目. [输入] 一个整数 n. [输出] 一个整数,表示有多少对 (x,y) 满足题意.答案对 109+7 取模. [输入样例] 2 [输出样例] 3 [提示] 样例说明 共有三个数对 (x,y) 满足条件,分别是 (3,6),(4,4) 和 (6,3). 数据范围与提示: 对于 30% 的数据,n≤100: 对于全部数据,1≤n≤106 . (这里不得不吐

【信息学奥赛一本通】第三部分_队列 ex2_3produce 产生数

给出一个整数n(n<=2000)(代码可适用n<=10^31)和k个变换规则(k<=15). 规则:1.1个数字可以变换成另1个数字: 2.规则中右边的数字不能为零. BFS 1 #include <stdio.h> 2 #include <string.h> 3 #define maxn 1000 4 5 char num[33]; 6 int len,q[maxn],Visited[11]; 7 long long ans = 1; 8 9 int main

信息学奥赛一本通 5.1 区间类动态规划

石子合并[loj 10147] /* dp[i][j]=max or min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]) i<=k<j */ #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; inline int re

信息学奥赛一本通 5.2 树形动态规划

题解在代码中 二叉苹果树[loj 10153] /* 若要留q条边便是要留q+1个点 所以记忆化搜索 dp[pos][ans]=max(dp[pos][ans],dp[l[pos]][k]+dp[r[pos]][ans-k-1]+a[pos]) 0<=k<=ans-1 */ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<c

【信息学奥赛一本通 提高组】第二章 二分与三分

一.二分 二分法,在一个单调有序的集合或函数中查找一个解,每次分为左右两部分,判断解在那个部分并调整上下界,直到找到目标元素,每次二分都将舍弃一般的查找空间,因此效率很高. 二分常见模型 1.二分答案 最小值最大(或是最大值最小)问题,这类双最值问题常常选用二分法求解,也就是确定答案后,配合贪心,DP等其他算法检验这个答案是否合理,将最优化问题转化为判定性问题.例如,将长度为n的序列ai分为最多m个连续段,求所有分法中每段和的最大值的最小是多少? 2.二分查找 用具有单调性的布尔表达式求解分界点

求后序遍历(信息学奥赛一本通 1339)

假设有棵树,长下面这个样子,它的前序遍历,中序遍历,后续遍历都很容易知道. PreOrder: GDAFEMHZ InOrder: ADEFGHMZ PostOrder: AEFDHZMG 现在,假设仅仅知道前序和中序遍历,如何求后序遍历呢?比如,已知一棵树的前序遍历是"GDAFEMHZ",而中序遍历是"ADEFGHMZ"应该如何求后续遍历? 第一步,root最简单,前序遍历的第一节点G就是root. 第二步,继续观察前序遍历GDAFEMHZ,除了知道G是root,