学习记录
快速幂
复杂度: O ( l o g n ) O(log\ n) O(log n)
代码实现:
long long binpow(long long a, long long b) {
long long res = 1;
while (b > 0) {
if (b & 1) res = res * a;
a = a * a;
b >>= 1;
}
return res;
}
逆元:
i n v ( a ) = a ( p − 2 ) ( m o d p ) inv(a) = a^{(p-2)} (mod\ p) inv(a)=a(p−2)(mod p)
应用:
计算 x n m o d m x^n\ mod\ m xn mod m
long long binpow(long long a, long long b, long long m) {
a %= m;
long long res = 1;
while (b > 0) {
if (b & 1) res = res * a % m;
a = a * a % m;
b >>= 1;
}
return res;
}
e.g. :
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MOD = 998244353;
long long binpow(long long a, long long b,long long MOD) {
a %= MOD;
long long res = 1;
while (b > 0) {
if (b & 1) res = (res * a) % MOD;
a = (a * a) % MOD;
b >>= 1;
}
return res;
}
signed main(){
int a,b;
b=MOD-2;
cout << binpow(2,b,MOD)<< endl <<
7*binpow(8,b,MOD)% MOD << endl <<
13*binpow(8,b,MOD)% MOD << endl;// 1/2 7/8 13/8
return 0;
}
线段树基础 :
-
在实际操作中,我们一般把数组的大小开到 4 n 4n 4n,即4倍数据范围。
-
线段树一般采用递归建树,从根节点开始向下递归建左子树右子树。
-
若 D i D_i Di表示区间 [ l , r ] [l,r] [l,r], 则区间大小为 r − l − 1 r-l-1 r−l−1。
-
递归边界: D i D_i Di表示的区间 [ l , r ] [l,r] [l,r]中肯定有 l = r l=r l=r且 D i = A i = A r D_i=A_i=A_r Di=Ai=Ar 。
线段树的建立:
void build(int rt,int l,int r)
{
if(l==r){
d[rt]=a[l];
return ;
}
int mid= l+r >> 1;
build(rt << 1, l , mid);
build(rt << 1 | 1,mid + 1, r);
push_up(rt << 1, rt << 1 | 1);
}