“21天好习惯”第一期-4 快速幂

21天零基础入门ACM

21天零基础入门ACM之 第4天

快速幂

什么是快速幂

说到快速幂,顾名思义就是快速算出某个数的n次幂,他的方法就是把指数二分,从而达到加快速度的目的。
举个例子:
      2 10 2^{10} 210
     可以写成 2 8 2^{8} 28 * 2 2 2^{2} 22

      1 0 11 10^{11} 1011;
     可以写成 2 8 2^{8} 28 * 2 2 2^{2} 22 * 2 1 2^{1} 21

      2 15 2^{15} 215;
     可以写成 2 8 2^{8} 28 * 2 4 2^{4} 24 * 2 2 2^{2} 22 * 2 1 2^{1} 21;

把一个n次幂,转化为2的倍数次幂的积
如 10 二进制为 1010 即为 8次幂和4次幂的积
2 8 2^{8} 28 即为 2 4 2^{4} 24的平方
由此来快速求幂

快速幂的模板

  • 第一种(不取模)
typedef longlong ll;
ll qpow(ll a, ll b) {   //a的b次方
    ll ans = 1;
    while (b) {
        if (b & 1)  //如果二进制的末尾为1,则ans乘以a  否则跳过
            ans *= a;
        b >>= 1;
        a *= a;
    }
    return ans;
}
  • 第二种(取模)
typedef longlong ll;
ll qpow(ll a, ll b, ll mod) {   //a的b次方 结果对mod取模
    ll ans = 1;
    a %= mod;
    while (b) {
        if (b & 1)
            (ans *= a) %= mod;
        b >>= 1;
        (a *= a) %= mod;
    }
    return ans % mod;
}

如果真的实在理解不了快速幂,直接背下来模板也可以。快速幂的模板很死,基本上不需要更改。

例题:

题目1:

链接:https://ac.nowcoder.com/acm/contest/8827/G
在这里插入图片描述
在这里插入图片描述

思路:

看到样例猜测结果是(m+1)的n次方,冲一发,就过来,嘿嘿😁。

代码如下
#include <bits/stdc++.h>
using namespace std;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define sc(x) scanf("%d",&x)
typedef long long ll; typedef unsigned long long ull; typedef long double ld;
inline ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
inline ll read() { ll s = 0, w = 1; char ch = getchar(); while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }    while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();    return s * w; }

const int mod=998244353;
const int N=1e5+7;

ll qpow(ll a, ll b) {
    ll ans = 1;
    while (b) {
        if (b & 1)
            ans *= a;
        b >>= 1;
        a *= a;
    }
    return ans;
}
ll qpow(ll a, ll b, ll mod) {
    ll ans = 1;
    a %= mod;
    while (b) {
        if (b & 1)
            (ans *= a) %= mod;
        b >>= 1;
        (a *= a) %= mod;
    }
    return ans % mod;
}

ll n,m;
int main(){
    cin>>n>>m;
    cout<<qpow(m+1,n,mod)<<endl;
}
题目2:

链接:https://ac.nowcoder.com/acm/problem/19115
在这里插入图片描述
在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define sc(x) scanf("%d",&x)
typedef long long ll; typedef unsigned long long ull; typedef long double ld;
inline ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
inline ll read() { ll s = 0, w = 1; char ch = getchar(); while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }    while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();    return s * w; }

ll qpow(ll a, ll b) {
    ll ans = 1;
    while (b) {
        if (b & 1)
            ans *= a;
        b >>= 1;
        a *= a;
    }
    return ans;
}
ll qpow(ll a, ll b, ll mod) {
    ll ans = 1;
    a %= mod;
    while (b) {
        if (b & 1)
            (ans *= a) %= mod;
        b >>= 1;
        (a *= a) %= mod;
    }
    return ans % mod;
}

const int mod=10007;
const int N=1e5+7;

ll n,m;

int main(){
    cin>>n>>m;
    if(n&1) cout<<qpow(m-1,n,mod)-m+1<<endl;
    else cout<<qpow(m-1,n,mod)+m-1<<endl;
}
题目3

链接:https://ac.nowcoder.com/acm/problem/14718
在这里插入图片描述
在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
typedef long long ll; typedef unsigned long long ull; typedef long double ld;
inline ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }

const int mod =1e9+7;
ll qpow(ll a, ll b) {
    ll ans = 1;
    while (b) {
        if (b & 1)
            ans *= a;
        b >>= 1;
        a *= a;
    }
    return ans;
}
ll qpow(ll a, ll b, ll mod) {
    ll ans = 1;
    a %= mod;
    while (b) {
        if (b & 1)
            (ans *= a) %= mod;
        b >>= 1;
        (a *= a) %= mod;
    }
    return ans % mod;
}
ll n,m;

int main(){
    while(cin>>n>>m){
        ll ans=qpow(m%mod,n,mod);
        ll ans2=(qpow((m-1)%mod,n-1,mod)*(m%mod))%mod;
        cout<<(ans-ans2+mod)%mod<<endl;
        //cout<<ans<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值