有关取模公式
(a * b)% c = (a%c) * (b%c) % c
a^b % c = (a % c)^b % c
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll ;
ll qmod(ll a,ll n,ll k)
{
ll ans = 1;
while(n)
{
if(n&1) ans =( ans * a ) % k;
a = a * a % k; // 不能写成 a *= a % k
n = n >> 1;
}
return ans;
}
int main()
{
ll x,y,z;
cin >> x >> y >> z;
cout << qmod(x,y,z);
return 0;
}
不会爆的模板
LL qpow(LL x,LL y,LL m)//二分思想
{
x=x%m;//防止第一个x*x就爆掉longlong
LL ans=1;//记录答案
while(y)// 注意如果y=0的话不会进入循环
{
if(y&1)//判断y是否是单数
{
ans=ans*x;
ans=ans%m;
}
x=x*x;
x=x%m;
y=y>>1;
}
ans=ans%m;//防止出现特殊数据:1^0%1=0的情况
return ans;
}
优化版大整数快速幂,O(nlogn),推荐使用!
求
a
n
%
m
o
d
a^{n} \ \% \ mod
an % mod
其实很好理解
比如我们要求
2
123
2^{123}
2123,首先我们尾指针指向
3
3
3,然后
a
n
s
=
a
n
s
∗
2
3
ans=ans * 2^{3}
ans=ans∗23,然后指向
2
2
2,
a
n
s
=
a
n
s
∗
(
2
10
)
2
ans=ans*(2^{10})^{2}
ans=ans∗(210)2,最后指向
1
1
1,
a
n
s
=
a
n
s
∗
(
2
100
)
1
ans=ans*(2^{100})^1
ans=ans∗(2100)1,最后得到就是
2
123
2^{123}
2123。
code:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=1e9+7;
ll q_pow(ll a, ll n){// 就是普通快速幂
ll ans = 1;while(n){
if(n & 1) ans=(ans*a)%mod;n>>=1;a=(a*a)%mod;
}return ans;
}
ll quickmod(ll a, char *n, int r)// 求a的n次方,r是尾指针
{
ll ans = 1;
while(r >= 0)// 倒着枚举次幂 n 的每一位
{
ll x = n[r] - '0';
ans = ans * q_pow(a, x) % mod;
a = q_pow(a, 10);
--r;
}
return ans;
}
int main()
{
char s[100009];
int a;
while(~scanf("%d",&a)) //求a^s%mod
{
scanf("%s", s);
int len = strlen(s);
printf("%lld\n", quickmod(a, s, len - 1));
}
return 0;
}