并查集
(1).种类
int find(int x)
{
if (x != fa[x])
fa[x] = find(fa[x]);
return fa[x];
} // 查询
void add(int x, int y)
{
int r1 = find(fa[x]), r2 = find(fa[y]);
fa[r1] = r2;
} // 合并
void solve()
{
int n, k;
cin >> n >> k;
int ans = 0;
for (int i = 1; i <= 3 * n; ++i)
{
fa[i] = i;
}
(2).带权
auto find = [&] (auto find, int x) -> int{
if(fa[x] != x){
int t = find(find, fa[x]);
d[x] = d[fa[x]] + d[x];
fa[x] = t;
}
return fa[x];
};
auto add = [&] (int u, int v, int c) -> void {
int uu = find(find, u), vv = find(find, v);
fa[uu] = vv;
d[uu] = ((d[v] - d[u] - c) % 3 + 3) % 3;
};
ST表
void init()
{
for (int j = 1; j <= 20; ++j)
{
for (int i = 1; (1 << j) - 1 + i <= n; ++i)
{
vec[i][j] = max(vec[i][j - 1], vec[i + (1 << j-1)][j - 1]);
}
}
}
int query(int le, int rg)
{
int len = log2(rg - le + 1);
int ret = max(vec[le][len], vec[rg - (1 << len) + 1][len]);
return ret;
}
KMP
vector<int> prefix_function(string s)
{
int n = (int)s.length();
vector<int> pi(n);
for (int i = 1; i < n; i++)
{
int j = pi[i - 1];
while (j > 0 && s[i] != s[j])
j = pi[j - 1];
if (s[i] == s[j])
j++;
pi[i] = j;
}
return pi;
}
vector<int> find_occurrences(string text, string pattern)
{
string cur = pattern + '#' + text;
int sz1 = text.size(), sz2 = pattern.size();
vector<int> v;
vector<int> lps = prefix_function(cur);
for (int i = sz2 + 1; i <= sz1 + sz2; i++)
{
if (lps[i] == sz2)
v.push_back(i - 2 * sz2);
}
return v;
}
树状数组
//单点查询
vector<int> tr;
int n;
int lowbit(int x)
{
return x & -x;
}
void add(int x, int k)
{
while (x <= n)
{
tr[x] += k;
x += lowbit(x);
}
}
int getsum(int x)
{
int ret = 0;
while (x)
{
ret += tr[x];
x -= lowbit(x);
}
return ret;
}
LCA
void dfs(int u)
{
vis[u] = 1;
for (auto i : e[u]){
if (vis[i] != 1){
dep[i] = dep[u] + 1;
fa[0