1.快速幂(取模)
ll qpow(ll a, ll b, ll k){
ll ans = 1;
while(b){
if(b & 1) ans = (ans % k) * (a % k) % k;
ans %= k;
a = (a % k) * (a % k) % k;
b >>= 1;
}
return ans %= k;
}
2.组合数(逆元)
ll c(ll n, ll m){
if(n < m) return 0;
else return f[n] * qpow(f[n - m], mod - 2) % mod * qpow(f[m], mod - 2) % mod;
}
3.快速排序
void qsort(int l, int r){
int mid = a[(l + r) / 2];
int i = l;
int j = r;
while(i <= j){
while(mid > a[i]) i++;
while(mid < a[j]) j--;
if(i <= j){
swap(a[i], a[j]);
i++;
j--;
}
}
if(l < j) qsort(l, j);
if(i < r) qsort(i, r);
}
4.树状数组
int lowbit(int x){
return x & (-x);
}
void add(int i, int k){
while(i <= n){
c[i] += k;
i += lowbit(i);
}
}
int sum(int i){
int ans = 0;
while(i > 0){
ans += c[i];
i -= lowbit(i);
}
return ans;
}
5.高精度乘法
int lena = strlen(a1);
int lenb = strlen(b1);
for(int i = 1; i <= lena; i++) a[i] = a1[lena - i] - '0';
for(int i = 1; i <= lenb; i++) b[i] = b1[lenb - i] - '0';
for(int i = 1; i <= lena; i++){
for(int j = 1; j <= lenb; j++){
c[i + j - 1] += a[i] * b[j];
}
}
int len = lena + lenb;
for(int i = 1; i <= len; i++) if(c[i] > 9){
c[i + 1] += c[i] / 10;
c[i] = c[i] % 10;
}
while(c[len] == 0 && len > 1) len--;
for(int i = len; i >= 1; i--) printf("%d", c[i]);
6.并查集
int query(int x){
if(f[x] == x) return x;
else return query(f[x]);
}
void merge(int x, int y){
int f1 = query(x);
int f2 = query(y);
if(f1 != f2) f[f1] = f2;
}
7.线性筛(O(N))
void getprime(int n){
memset(isprime, 1, sizeof(isprime));
isprime[1] = 0;
int cnt = 0;
for(int i = 2; i <= n; i++){
if(isprime[i]) prime[++cnt] = i;
for(int j = 1; j <= cnt && prime[j] * i <= n; j++){
isprime[prime[j] * i] = 0;
if(i % prime[j] == 0) break;
}
}
}
8.克鲁斯卡尔(求最小生成树)
ll kruskal(){
for(int i = 1; i <= n; i++) f[i] = i;
ll res = 0;
int cnt = 0;
for(int i = 1; i <= m; i++){
int a = find(e[i].u), b = find(e[i].v);
if(a != b){
f[a] = b;
res += e[i].a;
cnt++;
}
}
if(cnt != n - 1) return 0;
return res;
}
持续更新……