快速幂-慢速乘
//快速幂
long long q_poe(long long x, long long n, long long mod){
long long res = 1;
while(n > 0){
if(n & 1) {
res = (res * x) % m;
}
x = (x * x) % m;
n >>= 1; // 相当于 n /= 2;
}
return res;
}
//慢速乘
long long s_mul(long long a,long long b,long long mod){
long long res=0;
while(b){
if(b%2){
res=(res+a)%p;
}
a=(a+a)%p;
b/=2;
}
return res;
}
矩阵快速幂
// 矩阵快速幂
typedef vector<int> vec;
typedef vector<vec> mat;
typedef long long ll;
const int M = 1E9;
mat mul(mat &A, mat &B){
mat C(A.size(), vec(B[0].size()));
for(int i = 0; i < A.size(); i++){
for(int k = 0; k < B.size(); k++){
for(int j = 0; j < B[0].size(); j++){
C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % M;
}
}
}
return C;
}
mat pow(mat A, ll n){
mat B(A.size(), vec(A.size()));
for(int i = 0; i < A.size(); i++){
B[i][i] = 1;
}
while(n > 0){
if(n & 1) {
B = mul(B, A);
}
A = mul(A, A);
n >>= 1;
}
return B;
}
埃氏筛
//埃氏筛
int prime[maxn]; //存储素数的数组
bool is_prime[maxn]; //对应位置的数是否为素数
int a_shai(int n){
int p = 0;
for(int i = 0; i <= n; ++i){
is_prime[i] = true;
}
is_prime[0] = is_prime[1] = false;
for(int i = 2; i <= n; ++i){
if(is_prime[i]){
prime[p++] = i;
for(int j = i + i; j <= n; j += i){
is_prime[j] = false;
}
}
}
return p;
}
GCD
//递归 GCD
int gcd(int a, int b){
return b == 0 ? a : gcd(b, a % b);
}
快速选择
//快速选择算法
int quick_sort(int l, int r, int k){
if(l >= r){
return nums[k];
}
int i = l, j = r, x = nums[i + j >> 1];
while(i < j){
while(nums[i] < x){
i++;
}
while(nums[j] > x){
j--;
}
if(i < j){
swap(nums[i], nums[j]);
}
}
if(j >= k){
return quick_sort(l, j, k);
}else{
return quick_sort(j + 1, r, k);
}
}
前缀差分
//前缀和
pre[0] = nums[0];
for(int i = 1; i < n; i ++){
pre[i] = pre[i - 1] + nums[i];
}
for(int i = 1; i < nums.Length; i ++){
for(int j = 1; j < nums[i].Length; j++) {
pre[i][j] = pre[i - 1][j] + pre[i][j - 1] - pre[i - 1][j - 1] + nums[i][j];
}
}
//差分
void insert(int l, int r, int c){
b[l] += c;
b[r + 1] -= c;
}
for(int i = 1; i <= n; i++){
insert(i, i, a[i]);
}
void insert(int x1, int y1, int x2, int y2, int c){
b[x1][y1] += c;
b[x2 + 1][y1] -= c;
b[x1][y2 + 1] -= c;
b[x2 + 1][y2 + 1] += c;
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
insert(i, j, i, j, a[i][j]);
}
}
树状数组
//树状数组 (动态前缀和)
const int N = 100000;
int a[N], tr[N];
int n;
//求末位 0 函数
int lowbit(int x){
return x & -x;
}
//添加函数
void add(int x, int v){
for(int i = x; i <= n; i += lowbit(i)){
tr[i] += v;
}
}
//区间和函数
int query(int x){
int res = 0;
for(int i = x; i; i -= lowbit(i)){
res += tr[i];
}
}
逆序对
//逆序对
vector<int> tmp;
int count;
void mergeSort(vector<int>& nums, int l, int r) {
if(l >= r){
return;
}
int mid = (r - l) / 2 + l;
mergeSort(nums, l, mid);
mergeSort(nums, mid + 1, r);
int i = l, j = mid + 1;
int cur = 0;
while(i <= mid && j <= r) {
if(nums[i] <= nums[j]) {
tmp[cur++] = nums[i++];
}else {
tmp[cur++] = nums[j++];
count += mid - i + 1;
}
}
while (i <= mid) {
tmp[cur++] = nums[i++];
}
while (j <= r) {
tmp[cur++] = nums[j++];
}
for (int i = 0; i < r - l + 1; ++i) {
nums[l+i] = tmp[i];
}
}
tmp.resize((int)nums.size(), 0);
mergeSort(nums, 0, (int)nums.size() - 1);
