-
快读优化
template <typename T> void read(T &x)
{
bool mark = false;
char ch = getchar();
for(; ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') mark = true;
for(x = 0; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 3) + (x << 1) + ch - '0';
if(mark) x = -x;
return;
}
-
欧拉函数计算
int euler(int x)
{
int res = x;
for(int i = 2; i <= sqrt(x); ++ i)
{
if(x % i == 0)
{
res = res / i * (i - 1);
while(x % i == 0) x /= i;
}
if(x == 1) return res;
}
if(x > 1) res = res / x * (x - 1);
return res;
}
-
线性筛素数
void primes()
{
p.clear();
memset(vis, 0, sizeof(vis));
for(int i = 2; i <= n; ++ i)
{
if(!vis[i])
{
vis[i] = i;
p.push_back(i);
}
for(int j = 0; j < p.size(); ++ j)
{
if(p[j] > vis[i] || 1ll * p[j] * i > n) break;
vis[p[j] * i] = vis[i];
}
}
return;
}
-
最大公因数(欧几里得算法)
int gcd(int x, int y)
{
return y ? gcd(y, x % y) : x;
}
-
扩展欧几里得算法(逆元:同余方程)
void exgcd(int a, int b, int &d, int &x, int &y)
{
if(!b) d = a, x = 1, y = 0;
else
{
exgcd(b, a % b, d, y, x);
y -= x * (a / b);
}
return;
}
-
快速幂(逆元:费马小定理)
int power(int x, int y, int k)
{
int res = 1 % k;
while(y)
{
if(y & 1) res = 1ll * res * x % k;
y >>= 1;
x = 1ll * x * x % k;
}
return res;
}
-
树状数组
#define lowbit(x) x&(-x)
void add(int x, int v)
{
while(x <= n)
{
c[x] += v;
x += lowbit(x);
}
return;
}
int ask(int x)
{
int res = 0;
while(x)
{
res += c[x];
x -= lowbit(x);
}
return res;
}
-
线段树
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define lson p<<1,l,mid
#define rson p<<1|1,mid+1,r
#define wht 1,1,n
struct Segment
{
long long sum, flag;
inline void init(int v)
{
sum = v, flag = 0;
return;
}
inline void merge(struct Segment x, struct Segment y)
{
sum = x.sum + y.sum;
return;
}
} T[N << 2];
void spread(int p, int l, int r)
{
if(l != r && T[p].flag)
{
int mid = l + ((r - l) >> 1);
T[p << 1].flag += T[p].flag;
T[p << 1].sum += (mid - l + 1) * T[p].flag;
T[p << 1 | 1].flag += T[p].flag;
T[p << 1 | 1].sum += (r - mid) * T[p].flag;
}
T[p].flag = 0;
return;
}
void build(int p, int l, int r)
{
if(l == r)
{
int v;
read(v);
T[p].init(v);
return;
}
int mid = l + ((r - l) >> 1);
build(lson), build(rson);
T[p].merge(T[p << 1], T[p << 1 | 1]);
}
void modify(int p, int l, int r, int x, int v)
{
spread(p, l, r);
if(l == r)
{
T[p].sum += v;
return;
}
int mid = l + ((r - l) >> 1);
if(x <= mid) modify(lson, x, v);
else modify(rson, x, v);
T[p].merge(T[p << 1], T[p << 1 | 1]);
return;
}
void modify(int p, int l, int r, int L, int R, int v)
{
if(l >= L && r <= R)
{
T[p].flag += v;
T[p].sum += 1ll * (r - l + 1) * v;
return;
}
spread(p, l, r);
int mid = l + ((r - l) >> 1);
if(L <= mid) modify(lson, L, R, v);
if(R > mid) modify(rson, L, R, v);
T[p].merge(T[p << 1], T[p << 1 | 1]);
return;
}
long long query(int p, int l, int r, int L, int R)
{
if(l > R || r < L) return 0;
if(l >= L && r <= R)
{
return T[p].sum;
}
int mid = l + ((r - l) >> 1);
spread(p, l, r);
long long val = 0;
if(L <= mid) val = query(lson, L, R);
if(R > mid) val += query(rson, L, R);
return val;
}
-
单调栈
int t = 0;
for(int i = 1; i <= n; ++ i)
{
if(!t || a[s[t - 1]] >= a[i]) s[t ++] = i;
else
{
while(t && a[s[t - 1]] < a[i])
{
f[s[t - 1]] = i;
-- t;
}
s[t ++] = i;
}
}
-
单调队列(太基本了)
-
旅行商问题(TSP)
dp[0][1] = 0;
for(int S = 2; S < 1 << n; ++ S)
{
for(int i = 0; i < n; ++ i)
{
if((1 << i) & S)
{
int pre_state = S ^ (1 << i);
for(int j = 0; j < n; ++ j)
{
if((1 << j) & pre_state)
{
dp[i][S] = min(dp[i][S], dp[j][pre_state] + a[j][i]);
}
}
}
}
}
-
Floyd
for(int k = 1; k <= n; ++ k)
for(int i = 1; i <= n; ++ i)
for(int j = 1; j <= n; ++ j)
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j]);
-
Dijkstra
void Dijkstra(int S)
{
while(Q.size()) Q.pop();
memset(vis, false, sizeof(vis));
memset(dis, 0x3f, sizeof(dis));
Q.push(make_pair(0, S));
dis[S] = 0;
while(Q.size())
{
int u = Q.top().second; Q.pop();
if(vis[u]) continue;
vis[u] = true;
for(int i = 0; i < G[u].size(); ++ i)
{
int v = G[u][i], w = W[u][i];
if(dis[v] > dis[u] + w)
{
dis[v] = dis[u] + w;
Q.push(make_pair(-dis[v], v));
}
}
}
return;
}
-
SPFA
void Bellman_Ford()
{
while(Q.size()) Q.pop();
memset(inq, false, sizeof(inq));
for(int i = 1; i <= n; ++ i) dis[i] = INF;
Q.push(s);
dis[s] = 0;
inq[s] = true;
while(Q.size())
{
int u = Q.front();
Q.pop();
inq[u] = false;
for(int i = 0; i < G[u].size(); ++ i)
{
int v = G[u][i], w = W[u][i];
if(dis[v] > dis[u] + w)
{
dis[v] = dis[u] + w;
if(!inq[v]) Q.push(v), inq[v] = true;
}
}
}
return;
}
SPFA求负环
bool spfa()
{
while(Q.size()) Q.pop();
memset(inq, false, sizeof(inq));
memset(dis, 0x3f, sizeof(dis));
memset(cnt, 0, sizeof(cnt));
dis[1] = 0;
inq[1] = true;
Q.push(1);
while(Q.size())
{
int u = Q.front(); Q.pop();
inq[u] = false;
for(int i = 0; i < G[u].size(); ++ i)
{
int v = G[u][i], w = W[u][i];
if(dis[v] > dis[u] + w)
{
dis[v] = dis[u] + w;
cnt[v] = cnt[u] + 1;
if(cnt[v] >= n) return true;
if(!inq[v]) Q.push(v), inq[v] = true;
}
}
}
return false;
}
-
ST算法
void ST_prework()
{
int t = log(n) / log(2);
for(int j = 1; j <= t; ++ j)
{
for(int i = 1; i <= n - (1 << j) + 1; ++ i)
{
f[i][j] = max(f[i][j - 1], f[i + (1 << j - 1)][j - 1]);
}
}
return;
}
int k = log(r - l + 1) / log(2);
printf("%d
", max(f[l][k], f[r - (1 << k) + 1][k]));
-
最近公共祖先(树上倍增)
void BFS()
{
while(Q.size()) Q.pop();
memset(dep, 0, sizeof(dep));
Q.push(s);
dep[s] = 1;
while(Q.size())
{
int u = Q.front();
Q.pop();
for(int i = 0; i < G[u].size(); ++ i)
{
int v = G[u][i];
if(dep[v]) continue;
dep[v] = dep[u] + 1;
F[v][0] = u;
for(int i = 1; i <= t; ++ i) F[v][i] = F[F[v][i - 1]][i - 1];
Q.push(v);
}
}
return;
}
int LCA(int x, int y)
{
if(dep[x] > dep[y]) swap(x, y);
for(int i = t; i >= 0; -- i)
{
if(dep[F[y][i]] >= dep[x])
{
y = F[y][i];
}
}
if(x == y) return x;
for(int i = t; i >= 0; -- i)
{
if(F[x][i] != F[y][i])
{
x = F[x][i];
y = F[y][i];
}
}
return F[x][0];
}
-
Topsort
void Topsort()
{
while(Q.size()) Q.pop();
for(int i = 1; i <= n; ++ i) if(!deg[i]) Q.push(i);
while(Q.size())
{
int u = Q.front();
Q.pop();
for(int i = 0; i < G[u].size(); ++ i)
{
int v = G[u][i];
-- deg[v];
if(!deg[v]) Q.push(v);
}
}
return;
}
-
Kruskal
struct edge
{
int u, v, w;
inline bool operator <(const edge& lhs) const
{
return w < lhs.w;
}
} e[M];
int get(int x)
{
if(x == fa[x]) return x;
return fa[x] = get(fa[x]);
}
int main()
{
sort(e, e + m);
for(int i = 0; i < m; ++ i)
{
int u = e[i].u, v = e[i].v, v1 = get(u), v2 = get(v);
if(v1 == v2) continue;
fa[v1] = v2;
ans += e[i].w;
}
return 0;
}