dsu on tree 题集 + ac代码

文章目录

    • **入门讲解**
      • **[600E - Lomsat gelral](https://codeforces.ml/problemset/problem/600/E)**
      • **[树上数颜色](https://www.luogu.org/problemnew/show/U41492)**
      • **[570D - Tree Requests](https://codeforces.ml/problemset/problem/570/D)**
      • **[ 阔力梯的树](https://ac.nowcoder.com/acm/contest/4010/E)**
      • **[SGU - 507 Treediff](https://vjudge.net/problem/SGU-507/origin)**
      • **[HackerEarth, The Grass Type](https://www.hackerearth.com/practice/algorithms/graphs/depth-first-search/practice-problems/algorithm/the-grass-type/) **
      • **[E. Blood Cousins](https://codeforces.ml/problemset/problem/208/E)**
      • **[E. Blood Cousins Return](https://codeforces.ml/problemset/problem/246/E)**
      • **[F. Dominant Indices](https://codeforces.ml/problemset/problem/1009/F)**
      • **[D. Water Tree](https://codeforces.ml/problemset/problem/343/D)**
      • **[D. Tree and Queries](https://codeforces.ml/problemset/problem/375/D)**

入门讲解

创作者博客
简要概述:其实就是分治吧,对与每个节点的子节点,我们先遍历它的轻儿子,把访问记录删去,然后再遍历它的重儿子,把访问记录留下,然后再去暴力遍历这个节点的轻儿子统计答案。
这样可以严格使复杂度的上限是nlog⁡(n)n\log(n)nlog(n)

600E - Lomsat gelral

/*Author : lifehappy
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>#define mp make_pair
#define pb push_back
#define endl '\n'
#define mid (l + r >> 1)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define ls rt << 1
#define rs rt << 1 | 1using namespace std;typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;const double pi = acos(-1.0);
const double eps = 1e-7;
const int inf = 0x3f3f3f3f;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-')    f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return f * x;
}const int N = 1e5 + 10;int head[N], to[N << 1], nex[N << 1], cnt = 1;int n, col[N], sz[N], son[N];void add(int x, int y) {to[cnt] = y;nex[cnt] = head[x];head[x] = cnt++;
}void dfs(int rt, int fa) {sz[rt] = 1;for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa) continue;dfs(to[i], rt);if(!son[rt] || sz[to[i]] > sz[son[rt]]) son[rt] = to[i];sz[rt] += sz[to[i]];}
}ll now_son, maxn, sum, num[N], ans[N];void calc(int rt, int fa, int value) {num[col[rt]] += value;if(num[col[rt]] > maxn) {maxn = num[col[rt]];sum = col[rt];}else if(num[col[rt]] == maxn) sum += col[rt];for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa || to[i] == now_son) continue;calc(to[i], rt, value);}
}void dsu(int rt, int fa, bool keep) {for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa || to[i] == son[rt]) continue;dsu(to[i], rt, 0);}if(son[rt]) {dsu(son[rt], rt, 1);now_son = son[rt];}calc(rt, fa, 1);;now_son = 0;ans[rt] = sum;if(!keep) {calc(rt, fa, -1);maxn = sum = 0;}
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);n = read();for(int i = 1; i <= n; i++) col[i] = read();for(int i = 1; i < n; i++) {int x = read(), y = read();add(x, y);add(y, x);}dfs(1, 0);dsu(1, 0, 0);for(int i = 1; i <= n; i++) {printf("%lld%c", ans[i], i == n ? '\n' : ' ');}return 0;
}

树上数颜色

/*Author : lifehappy
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>#define mp make_pair
#define pb push_back
#define endl '\n'
#define mid (l + r >> 1)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define ls rt << 1
#define rs rt << 1 | 1using namespace std;typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;const double pi = acos(-1.0);
const double eps = 1e-7;
const int inf = 0x3f3f3f3f;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-')    f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return f * x;
}const int N = 1e5 + 10;int head[N], to[N << 1], nex[N << 1], cnt = 1;int l[N], r[N], rk[N], col[N], son[N], sz[N], tot, n, m;void add(int x, int y) {to[cnt] = y;nex[cnt] = head[x];head[x] = cnt++;
}void dfs(int rt, int fa) {rk[++tot] = rt;l[rt] = tot;sz[rt] = 1;for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa) continue;dfs(to[i], rt);sz[rt] += sz[to[i]];if(!son[rt] || sz[to[i]] > sz[son[rt]]) son[rt] = to[i];}r[rt] = tot;
}int ans[N], num[N], sum;void dfs(int rt, int fa, bool keep) {for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa || to[i] == son[rt]) continue;dfs(to[i], rt, 0);}if(son[rt]) dfs(son[rt], rt, 1);for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa || to[i] == son[rt]) continue;for(int j = l[to[i]]; j <= r[to[i]]; j++) {if(!num[col[rk[j]]]++) sum++;}}if(!num[col[rt]]++) sum++;ans[rt] = sum;if(!keep) {sum = 0;for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa) continue;for(int j = l[to[i]]; j <= r[to[i]]; j++) {num[col[rk[j]]]--;}}num[col[rt]]--;}
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);n = read();for(int i = 1; i < n; i++) {int x = read(), y = read();add(x, y);add(y, x);}dfs(1, 0);for(int i = 1; i <= n; i++) col[i] = read();dfs(1, 0, 1);m = read();for(int i = 1; i <= m; i++) {int rt = read();printf("%d\n", ans[rt]);}return 0;
}

570D - Tree Requests

/*Author : lifehappy
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>#define mp make_pair
#define pb push_back
#define endl '\n'
#define mid (l + r >> 1)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define ls rt << 1
#define rs rt << 1 | 1using namespace std;typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;const double pi = acos(-1.0);
const double eps = 1e-7;
const int inf = 0x3f3f3f3f;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-')    f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return f * x;
}const int N = 5e5 + 10;int head[N], to[N], nex[N], cnt = 1;char str[N];int sz[N], dep[N], son[N], n, m, v[N], h[N];struct Node {int h, id;
};void add(int x, int y) {to[cnt] = y;nex[cnt] = head[x];head[x] = cnt++;
}void dfs(int rt, int fa) {dep[rt] = dep[fa] + 1;sz[rt] = 1;for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa) continue;dfs(to[i], rt);sz[rt] += sz[to[i]];if(!son[rt] || sz[to[i]] > sz[son[rt]]) son[rt] = to[i];}
}bitset<30> num[N];int now_son, ans[N];vector<Node> query[N];void calc(int rt, int fa) {int now = str[rt] - 'a';if(num[dep[rt]][now]) num[dep[rt]][now] = 0;else num[dep[rt]][now] = 1;for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa || to[i] == now_son) continue;calc(to[i], rt);}
}void del(int rt, int fa) {int now = str[rt] - 'a';num[dep[rt]][now] = 0;for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa) continue;del(to[i], rt);}
}void dsu(int rt, int fa, bool keep) {for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa || to[i] == son[rt]) continue;dsu(to[i], rt, 0);}if(son[rt]) {dsu(son[rt], rt, 1);now_son = son[rt];}calc(rt, fa);now_son = 0;for(auto i : query[rt]) {int h = i.h, id = i.id;ans[id] = num[h].count() <= 1;  }if(!keep) del(rt, fa);
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);scanf("%d %d", &n, &m);for(int i = 2; i <= n; i++) {int x; scanf("%d", &x);add(x, i);}scanf("%s", str + 1);dfs(1, 0);for(int i = 1; i <= m; i++) {int v, h;scanf("%d %d", &v, &h);query[v].pb({h, i});}dsu(1, 0, 1);for(int i = 1; i <= m; i++) {puts(ans[i] ? "Yes" : "No");}return 0;
}

阔力梯的树

/*Author : lifehappy
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>#define mp make_pair
#define pb push_back
#define endl '\n'
#define mid (l + r >> 1)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define ls rt << 1
#define rs rt << 1 | 1using namespace std;typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;const double pi = acos(-1.0);
const double eps = 1e-7;
const int inf = 0x3f3f3f3f;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-')    f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return f * x;
}const int N = 1e5 + 10;int head[N], to[N << 1], nex[N << 1], cnt = 1;int sz[N], l[N], r[N], son[N], rk[N], n, tot, now_son;void add(int x, int y) {to[cnt] = y;nex[cnt] = head[x];head[x] = cnt++;
}void dfs(int rt, int fa) {rk[++tot] = rt;sz[rt] = 1, l[rt] = tot;for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa) continue;dfs(to[i], rt);if(!son[rt] || sz[to[i]] > sz[son[rt]]) son[rt] = to[i];sz[rt] += sz[to[i]];}r[rt] = tot;
}set<int> st;ll ans[N], sum;void add(int x) {auto it = st.lower_bound(x);if(st.empty()) {st.insert(x);return;}if(it == st.end()) {--it;sum += 1ll * (x - *it) * (x - *it);st.insert(x);return;}if(it == st.begin()) {sum += 1ll * (*it - x) * (*it - x);st.insert(x);return;}int vr = *it, vl = *--it;sum += 1ll * (vr - x) * (vr - x) + 1ll * (x - vl) * (x - vl) - 1ll * (vr - vl) * (vr - vl);st.insert(x);
}void dsu(int rt, int fa, bool keep) {for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa || to[i] == son[rt]) continue;dsu(to[i], rt, 0);}if(son[rt]) {now_son = son[rt];dsu(son[rt], rt, 1);}for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa || to[i] == son[rt]) continue;for(int j = l[to[i]]; j <= r[to[i]]; j++) {add(rk[j]);}}add(rt);ans[rt] = sum;if(!keep) {sum = 0;st.clear();}
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);n = read();for(int i = 2; i <= n; i++) {int x = read();add(x, i);add(i, x);}dfs(1, 0);dsu(1, 0, 1);for(int i = 1; i <= n; i++) {printf("%lld\n", ans[i]);}return 0;
} 

SGU - 507 Treediff

/*Author : lifehappy
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>#define mp make_pair
#define pb push_back
#define endl '\n'
#define mid (l + r >> 1)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define ls rt << 1
#define rs rt << 1 | 1using namespace std;typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;const double pi = acos(-1.0);
const double eps = 1e-7;
const int inf = 0x3f3f3f3f;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-')    f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return f * x;
}const int N = 1e5 + 10;int head[N], to[N << 1], nex[N << 1], cnt = 1;int l[N], r[N], rk[N], col[N], son[N], sz[N], tot, n, m;void add(int x, int y) {to[cnt] = y;nex[cnt] = head[x];head[x] = cnt++;
}void dfs(int rt, int fa) {rk[++tot] = rt;l[rt] = tot;sz[rt] = 1;for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa) continue;dfs(to[i], rt);sz[rt] += sz[to[i]];if(!son[rt] || sz[to[i]] > sz[son[rt]]) son[rt] = to[i];}r[rt] = tot;
}int ans[N], minn;set<int> st;void add(int x) {if(st.empty()) {st.insert(x);return ;}auto it = st.lower_bound(x);if(it == st.end()) {it--;minn = min(minn, x - *it);}else if(it == st.begin()) {minn = min(minn, *it - x);}else {int r = *it;it--;int l = *it;minn = min({minn, r - x, x - l});}st.insert(x);
}void dfs(int rt, int fa, bool keep) {for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa || to[i] == son[rt]) continue;dfs(to[i], rt, 0);}if(son[rt]) dfs(son[rt], rt, 1);for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa || to[i] == son[rt]) continue;for(int j = l[to[i]]; j <= r[to[i]]; j++) {if(col[rk[j]] != 2147483647) add(col[rk[j]]);}}if(col[rt] != 2147483647) add(col[rt]);ans[rt] = minn;if(!keep)   st.clear(), minn = 2147483647;
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);n = read(), m = read();ans[1] = col[1] = 2147483647;for(int i = 2; i <= n; i++) {int x = read();add(x, i);ans[i] = col[i] = 2147483647;}for(int i = n - m + 1; i <= n; i++) {col[i] = read();}dfs(1, 0);minn = 2147483647;dfs(1, 0, 1);for(int i = 1; i <= n - m; i++) {printf("%d%c", ans[i], i == n - m ? '\n' : ' ');}return 0;
}

**HackerEarth, The Grass Type **

/*Author : lifehappy
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>#define mp make_pair
#define pb push_back
#define endl '\n'
#define mid (l + r >> 1)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define ls rt << 1
#define rs rt << 1 | 1using namespace std;typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;const double pi = acos(-1.0);
const double eps = 1e-7;
const int inf = 0x3f3f3f3f;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-')    f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return f * x;
}const int N = 1e5 + 10;int head[N], to[N << 1], nex[N << 1], cnt = 1;int l[N], r[N], rk[N], col[N], son[N], sz[N], tot, n, m;
ll ans;void add(int x, int y) {to[cnt] = y;nex[cnt] = head[x];head[x] = cnt++;
}void dfs(int rt, int fa) {rk[++tot] = rt;l[rt] = tot;sz[rt] = 1;for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa) continue;dfs(to[i], rt);sz[rt] += sz[to[i]];if(!son[rt] || sz[to[i]] > sz[son[rt]]) son[rt] = to[i];}r[rt] = tot;
}map<int, int> MP;void dfs(int rt, int fa, bool keep) {for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa || to[i] == son[rt]) continue;dfs(to[i], rt, 0);}if(son[rt]) dfs(son[rt], rt, 1);for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa || to[i] == son[rt]) continue;for(int j = l[to[i]]; j <= r[to[i]]; j++) {if(col[rt] % col[rk[j]]) continue;ans += MP[col[rt] / col[rk[j]]];}for(int j = l[to[i]]; j <= r[to[i]]; j++) {MP[col[rk[j]]]++;}}ans += MP[1];MP[col[rt]]++;if(!keep) {MP[col[rt]]--;for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa) continue;for(int j = l[to[i]]; j <= r[to[i]]; j++) {MP[col[rk[j]]]--;}}}
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);n = read();for(int i = 1; i < n; i++) {int x = read(), y = read();add(x, y);add(y, x);}dfs(1, 0);for(int i = 1; i <= n; i++) col[i] = read();dfs(1, 0, 1);printf("%lld\n", ans);return 0;
}

E. Blood Cousins

/*Author : lifehappy
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>#define mp make_pair
#define pb push_back
#define endl '\n'
#define mid (l + r >> 1)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define ls rt << 1
#define rs rt << 1 | 1using namespace std;typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;const double pi = acos(-1.0);
const double eps = 1e-7;
const int inf = 0x3f3f3f3f;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-')    f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return f * x;
}const int N = 1e5 + 10;int head[N], to[N], nex[N], cnt = 1;int sz[N], son[N], dep[N], fa[N][21], l[N], r[N], rk[N], tot, n, m;bool root[N];void add(int x, int y) {to[cnt] = y;nex[cnt] = head[x];head[x] = cnt++;
}void dfs(int rt, int f) {l[rt] = ++tot;rk[tot] = rt;fa[rt][0] = f;dep[rt] = dep[f] + 1;sz[rt] = 1;for(int i = 1; (1 << i) <= dep[rt]; i++) {fa[rt][i] = fa[fa[rt][i - 1]][i - 1];}for(int i = head[rt]; i; i = nex[i]) {if(to[i] == f) continue;dfs(to[i], rt);sz[rt] += sz[to[i]];if(!son[rt] || sz[to[i]] > sz[son[rt]]) son[rt] = to[i];}r[rt] = tot;
}int find(int x, int k) {int t = dep[x] - k;for(int i = 20; i >= 0; i--)if(dep[fa[x][i]] > t) x = fa[x][i];return fa[x][0];
}int ans[N], num[N];vector<pii> ask[N];void dfs(int rt, int f, bool keep) {for(int i = head[rt]; i; i = nex[i]) {if(to[i] == f || to[i] == son[rt]) continue;dfs(to[i], rt, 0);}if(son[rt]) dfs(son[rt], rt, 1);for(int i = head[rt]; i; i = nex[i]) {if(to[i] == f || to[i] == son[rt]) continue;for(int j = l[to[i]]; j <= r[to[i]]; j++) {num[dep[rk[j]]]++;}}num[dep[rt]]++;for(auto i : ask[rt]) {int Dep = dep[rt] + i.first, id = i.second;ans[id] = num[Dep] - 1;}if(!keep) {num[dep[rt]]--;for(int i = head[rt]; i; i = nex[i]) {if(to[i] == f) continue;for(int j = l[to[i]]; j <= r[to[i]]; j++) {num[dep[rk[j]]]--;}}}
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);n = read();for(int i = 1; i <= n; i++) {int x = read();if(!x) {root[i] = true;continue;}add(x, i);}for(int i = 1; i <= n; i++) {if(root[i]) {dfs(i, 0);}}m = read();for(int i = 1; i <= m; i++) {int x = read(), y = read();int fa = find(x, y);if(fa == 0) {ans[i] = 0;}else {ask[fa].pb(mp(y, i));}}for(int i = 1; i <= n; i++) {if(root[i]) {dfs(i, 0, 0);}}for(int i = 1; i <= m; i++) {printf("%d%c", ans[i], i == m ? '\n' : ' ');}return 0;
}

E. Blood Cousins Return

/*Author : lifehappy
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>#define mp make_pair
#define pb push_back
#define endl '\n'
#define mid (l + r >> 1)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define ls rt << 1
#define rs rt << 1 | 1using namespace std;typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;const double pi = acos(-1.0);
const double eps = 1e-7;
const int inf = 0x3f3f3f3f;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-')    f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return f * x;
}const int N = 2e5 + 10;int head[N], to[N], nex[N], cnt = 1;int sz[N], son[N], dep[N], l[N], r[N], rk[N], tot, n, m;string col[N];bool root[N];void add(int x, int y) {to[cnt] = y;nex[cnt] = head[x];head[x] = cnt++;
}void dfs(int rt, int fa) {sz[rt] = 1, dep[rt] = dep[fa] + 1;l[rt] = ++tot, rk[tot] = rt;for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa) continue;dfs(to[i], rt);if(!son[rt] || sz[to[i]] > sz[son[rt]]) son[rt] = to[i];sz[rt] += sz[to[i]];}r[rt] = tot;
}set<string> st[N];vector<pii> ask[N];int ans[N];void dfs(int rt, int fa, bool keep) {for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa || to[i] == son[rt]) continue;dfs(to[i], rt, 0);}if(son[rt]) dfs(son[rt], rt, 1);for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa || to[i] == son[rt]) continue;for(int j = l[to[i]]; j <= r[to[i]]; j++) {st[dep[rk[j]]].insert(col[rk[j]]);}}st[dep[rt]].insert(col[rt]);for(auto i : ask[rt]) {int Dep = dep[rt] + i.first, id = i.second;ans[id] = st[Dep].size();}if(!keep) {for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa) continue;for(int j = l[to[i]]; j <= r[to[i]]; j++) {st[dep[rk[j]]].erase(col[rk[j]]);}}st[dep[rt]].erase(col[rt]);}
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);cin >> n;for(int i = 1; i <= n; i++) {cin >> col[i];int x; cin >> x;if(!x) root[i] = true;else {add(x, i);}}for(int i = 1; i <= n; i++) {if(root[i]) dfs(i, 0);}cin >> m;for(int i = 1; i <= m; i++) {int x, y;cin >> x >> y;ask[x].pb(mp(y, i));}for(int i = 1; i <= n; i++) {if(root[i]) dfs(i, 0, 0);}for(int i = 1; i <= m; i++) {cout << ans[i] << endl;}return 0;
}

F. Dominant Indices

/*Author : lifehappy
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>#define mp make_pair
#define pb push_back
#define endl '\n'
#define mid (l + r >> 1)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define ls rt << 1
#define rs rt << 1 | 1using namespace std;typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;const double pi = acos(-1.0);
const double eps = 1e-7;
const int inf = 0x3f3f3f3f;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-')    f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return f * x;
}const int N = 1e6 + 10;int head[N], to[N << 1], nex[N << 1], cnt = 1;int sz[N], dep[N], son[N], l[N], r[N], rk[N], tot, n;void add(int x, int y) {to[cnt] = y;nex[cnt] = head[x];head[x] = cnt++;
}void dfs(int rt, int fa) {sz[rt] = 1, l[rt] = ++tot;rk[tot] = rt, dep[rt] = dep[fa] + 1;for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa) continue;dfs(to[i], rt);sz[rt] += sz[to[i]];if(!son[rt] || sz[to[i]] > sz[son[rt]]) son[rt] = to[i];}r[rt] = tot;
}int ans[N], num[N], now_ans, maxn;void dfs(int rt, int fa, bool keep) {for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa || to[i] == son[rt]) continue;dfs(to[i], rt, 0);}if(son[rt]) dfs(son[rt], rt, 1);for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa || to[i] == son[rt]) continue;for(int j = l[to[i]]; j <= r[to[i]]; j++) {int Dep = dep[rk[j]];num[Dep]++;if(num[Dep] > maxn) {maxn = num[Dep];now_ans = Dep;}else if(num[Dep] == maxn && Dep < now_ans) now_ans = Dep;}}int Dep = dep[rt];num[Dep]++;if(num[Dep] > maxn) {maxn = num[Dep];now_ans = Dep;}else if(num[Dep] == maxn && Dep < now_ans) now_ans = Dep;ans[rt] = now_ans - Dep;if(!keep) {for(int i = l[rt]; i <= r[rt]; i++) {int Dep = dep[rk[i]];num[Dep]--;}now_ans = maxn = 0;}
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);n = read();for(int i = 1; i < n; i++) {int x = read(), y = read();add(x, y);add(y, x);}dfs(1, 0);dfs(1, 0, 1);for(int i = 1; i <= n; i++) {printf("%d\n", ans[i]);}return 0;
}

D. Water Tree

据说能dsuontreedsu\ on\ treedsu on tree,因为看到树链剖分好些就用树链剖分实现了。

/*Author : lifehappy
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>#define mp make_pair
#define pb push_back
#define endl '\n'
#define mid (l + r >> 1)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define ls rt << 1
#define rs rt << 1 | 1using namespace std;typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;const double pi = acos(-1.0);
const double eps = 1e-7;
const int inf = 0x3f3f3f3f;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-')    f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return f * x;
}const int N = 5e5 + 10;int head[N], to[N << 1], nex[N << 1], cnt = 1, n, m;int sz[N], son[N], fa[N], dep[N], rk[N], id[N], top[N], l[N], r[N], tot;int tree[N << 2], lazy[N << 2];void dfs1(int rt, int f) {sz[rt] = 1, fa[rt] = f;dep[rt] = dep[f] + 1;for(int i = head[rt]; i; i = nex[i]) {if(to[i] == f) continue;dfs1(to[i], rt);sz[rt] += sz[to[i]];if(!son[rt] || sz[to[i]] > sz[son[rt]]) son[rt] = to[i];}
}void dfs2(int rt, int tp) {id[rt] = l[rt] = ++tot;top[rt] = tp, rk[tot] = rt;if(!son[rt]) {r[rt] = tot;return ;}dfs2(son[rt], tp);for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa[rt] || to[i] == son[rt]) continue;dfs2(to[i], to[i]);}r[rt] = tot;
}void push_down(int rt) {if(lazy[rt] != -1) {lazy[ls] = lazy[rs] = lazy[rt];tree[ls] = tree[rs] = lazy[rt];lazy[rt] = -1;}
}void update(int rt, int l, int r, int L, int R, int value) {if(l >= L && r <= R) {lazy[rt] = value;tree[rt] = value;return ;}push_down(rt);if(L <= mid) update(lson, L, R, value);if(R > mid)  update(rson, L, R, value);
}int query(int rt, int l, int r, int L, int R) {if(l == r) {return tree[rt];}push_down(rt);if(L <= mid) return query(lson, L, R);return query(rson, L, R);
}void add(int x, int y) {to[cnt] = y;nex[cnt] = head[x];head[x] = cnt++;
}void change(int x, int y) {while(top[x] != top[y]) {if(dep[top[x]] < dep[top[y]]) swap(x, y);update(1, 1, n, id[top[x]], id[x], 0);x = fa[top[x]];}if(dep[x] > dep[y]) swap(x, y);update(1, 1, n, id[x], id[y], 0);
}void print(int rt, int l, int r) {if(l == r) {printf("%d ", tree[rt]);return ;}push_down(rt);print(lson);print(rson);
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);memset(lazy, -1, sizeof lazy);n = read();for(int i = 1; i < n; i++) {int x = read(), y = read();add(x, y);add(y, x);}dfs1(1, 0);dfs2(1, 1);m = read();for(int i = 1; i <= m; i++) {int op = read(), u = read();if(op == 1) {update(1, 1, n, l[u], r[u], 1);}else if(op == 2) {change(1, u);}else {printf("%d\n", query(1, 1, n, id[u], id[u]));}}return 0;
}

D. Tree and Queries

这道题目之前是用莫队写过,这次用dsuontreedsu\ on\ treedsu on tree重新写了一遍。

/*Author : lifehappy
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>#define mp make_pair
#define pb push_back
#define endl '\n'
#define mid (l + r >> 1)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define ls rt << 1
#define rs rt << 1 | 1using namespace std;typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;const double pi = acos(-1.0);
const double eps = 1e-7;
const int inf = 0x3f3f3f3f;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-')    f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}return f * x;
}const int N = 2e5 + 10;int head[N], to[N << 1], nex[N << 1], cnt = 1;int sz[N], son[N], col[N], l[N], r[N], rk[N], tot, n, m;void add(int x, int y) {to[cnt] = y;nex[cnt] = head[x];head[x] = cnt++;
}void dfs(int rt, int fa) {sz[rt] = 1, l[rt] = ++tot, rk[tot] = rt;for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa) continue;dfs(to[i], rt);sz[rt] += sz[to[i]];if(!son[rt] || sz[to[i]] > sz[son[rt]]) son[rt] = to[i];}r[rt] = tot;
}int ans[N], num[N], sum[N];vector<pii> ask[N];void add(int x) {sum[++num[x]]++;
}void del(int x) {sum[num[x]--]--;
}void dfs(int rt, int fa, bool keep) {for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa || to[i] == son[rt]) continue;dfs(to[i], rt, 0);}if(son[rt]) dfs(son[rt], rt, 1);for(int i = head[rt]; i; i = nex[i]) {if(to[i] == fa || to[i] == son[rt]) continue;for(int j = l[to[i]]; j <= r[to[i]]; j++) {add(col[rk[j]]);}}add(col[rt]);for(auto i : ask[rt]) {int minn = i.first, id = i.second;ans[id] = sum[minn];}if(!keep) {for(int j = l[rt]; j <= r[rt]; j++) {del(col[rk[j]]);}}
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);n = read(), m = read();for(int i = 1; i <= n; i++) col[i] = read();for(int i = 1; i < n; i++) {int x = read(), y = read();add(x, y);add(y, x);}dfs(1, 0);for(int i = 1; i <= m; i++) {int x = read(), y = read();ask[x].pb(mp(y, i));}dfs(1, 0, 1);for(int i = 1; i <= m; i++) {printf("%d\n", ans[i]);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/314293.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Kubectl部署应用

目录 使用Kubectl部署应用 Kubectl部署流程 部署一个简单的Demo网站 使用Kubectl部署应用一旦运行了Kubernetes集群&#xff0c;就可以在其上部署容器化应用程序。因此在开始之前&#xff0c;我们需要先确保集群已经准备就绪&#xff0c;无论是使用Minikube还是kubeadm创建的集…

SP22343 NORMA2 - Norma(分治优化复杂度)

SP22343 NORMA2 - Norma 一看就像是一个序列分治的题目&#xff0c;求解序列上区间长度乘区间最大值最小值的和&#xff0c;然后考虑如何处理&#xff0c;分治之后每次就可以将右边部分分成三部分&#xff0c;然后对于这三部分可以批量求和&#xff0c;这样就起到优化复杂度的…

Docker系列之.NET Core入门(三)

在Docker生态系统中除了上一节所讲解的基本概念&#xff0c;还有其他专业术语&#xff0c;本文我们将一笔带过&#xff0c;同时会开始陆续进入到在.NET Core中使用Docker。专业术语Docker Engine&#xff08;Docker引擎&#xff09;&#xff1a;客户端 - 服务器应用程序。Docke…

P3911 最小公倍数之和 (atcoder C - LCMs)(反演)

P3911 最小公倍数之和 推式子 ∑i1n∑j1nlcm(ai,aj)下面的nmax(ai)&#xff0c;ci为i在原数组中出现的次数∑i1n∑j1nijgcd(ij)cicj∑d1n1d∑i1n∑j1nijcicj(gcd(i,j)d)∑d1nd∑i1nd∑j1ndijcidcjd∑k∣gcd(i,j)μ(k)∑d1nd∑k1ndμ(k)k2∑i1nkd∑j1nkdijcikdcjkd∑t1nt(∑i1n…

P5502 [JSOI2015]最大公约数(gcd性质/min性质/分治)

P5502 [JSOI2015]最大公约数 对于求解(r-l1)*gcd(l,r)的最大值&#xff0c;首先我们有一个性质&#xff0c;就是一个前缀的gcd本质不同个数只有log个&#xff0c;所以我们可以利用这个性质&#xff0c;然后每次分治处理&#xff0c;每一层的复杂度可以做到O(n)因为枚举前缀后缀…

2019南昌网络赛G. tsy‘s number(反演 + 积性函数O(n)预处理)

tsy’s number 推式子 ∑i1n∑j1n∑k1nϕ(i)ϕ(j2)ϕ(k3)ϕ(i)ϕ(j)ϕ(k)ϕ(gcd(i,j,k))我们假定jp1k1p2k2p3p3……pnkn&#xff0c;有ϕ(j)p1k1−1(p1−1)p2k2−1(p2−1)p3k3−1(p3−1)……pnkn−1(pn−1)&#xff0c;ϕ(j2)p12k1−1(p1−1)p22k2−1(p2−1)p32k3−1(p3−1)……

#2989. 数列(cdq分治/曼哈顿距离)

#2989. 数列 给定一个长度为n的正整数数列a[i]。 定义2个位置的graze值为两者位置差与数值差的和&#xff0c;即graze(x,y)|x-y||a[x]-a[y]|。 2种操作&#xff08;k都是正整数&#xff09;&#xff1a; 1.Modify x k&#xff1a;将第x个数的值修改为k。 2.Query x k&#xff…

通过Blazor使用C#开发SPA单页面应用程序(4) - Ant Design

通过Blazor使用C#开发SPA单页面应用程序(1)通过Blazor使用C#开发SPA单页面应用程序(2)通过Blazor使用C#开发SPA单页面应用程序(3)前面学习了Blazor的特点、环境搭建及基础知识&#xff0c;现在我们尝试的做个实际的组件。Ant Design是蚂蚁金服是基于Ant Design设计体系的 UI 组…

POJ 1741 Tree(点分治)

POJ 1741 Tree 思路 男人八题中的一题&#xff0c;写完这题算是18\frac{1}{8}81​个男人了&#xff01; 这题是树上距离的计数问题&#xff0c;能够通过巧妙地排序加双指针来解决&#xff0c; 统计距离应该大家都会地&#xff0c;我就来说明一下如何计数吧。 假设我们已经求…

P1975 [国家集训队]排队(三维偏序)

P1975 [国家集训队]排队 查询逆序对数目&#xff0c;交换两个数的位置 首先逆序对是一个经典的二维偏序问题&#xff0c;然后现在问题变为静态&#xff0c;我们可以使用三维偏序来处理多出来的限制。或者也可以使用带修主席树处理。

Mercurial黄昏,Bitbucket宣布全面转向Git

源代码托管平台 Bitbucket 宣布将逐步放弃对版本控制系统 Mercurial 的支持。Bitbucket 推出于 2008 年&#xff0c;当时集中式版本控制是比较普遍的&#xff0c;Mercurial 是其中的典型代表&#xff0c;但是当前 Git 才是主流&#xff0c;它已经成为了大部分开源项目的首选版本…

HDU 4812 D Tree (点分治) (2013ACM/ICPC亚洲区南京站现场赛)

HDU 4812 D Tree 思路 点对距离相等并且要求输出字典序最小的点对&#xff0c;距离相等不就是点分治裸题了嘛&#xff0c; 照着这个思路出发我们只要记录下所有点对是满足要求的&#xff0c;然后再去找字典序最小的点对就行了&#xff0c; 接下来就是考虑如何求最小点对了&…

P2754 [CTSC1999]家园 / 星际转移问题(网络流)

P2754 [CTSC1999]家园 / 星际转移问题 经典问题&#xff0c;利用分层图来跑网络流。

使用 Azure DevTest Lab 搭建云端开发测试环境

点击上方蓝字关注“汪宇杰博客”导语程序员和测试工程师经常需要自己搭环境用于开发和测试目的&#xff0c;这些机器可能只会使用很短一段时间。通常我们会在本机使用 Hyper-V、VMWare 之类的虚拟机产品&#xff0c;或者使用企业IT管理员分配的虚拟机去完成这项工作。然而安装配…

dotNET Core WebAPI 统一处理(返回值、参数验证、异常)

现在 Web 开发比较流行前后端分离现在 Web 开发比较流行前后端分离&#xff0c;我们的产品也是一样&#xff0c;前端使用Vue&#xff0c;后端使用 dotNet Core WebAPI &#xff0c;在写 API 的过程中有很多地方需要统一处理文档参数验证返回值异常处理本文就说说 API 的统一处理…

HDU 4059 The Boss on Mars (容斥)(2011 Asia Dalian Regional Contest)

The Boss on Mars 思路 显然我们可以求得∑i1ni46n515n410n3−n30\sum_{i 1} ^{n} i ^ 4 \frac{6n^5 15n^4 10n ^3 - n}{30}∑i1n​i4306n515n410n3−n​&#xff0c;接下来就是考虑把其中不与nnn互质的数给踢出去了&#xff0c;显然我们可以考虑容斥。 假设np1a1p2a2p3…

P2764 最小路径覆盖问题(网络流)

P2764 最小路径覆盖问题 最小链覆盖问题&#xff0c;关键在于怎么转化为网络流问题&#xff0c;我们可以发现网络流的常见套路就是将一个点拆成出点和入点来处理&#xff0c;对于一条链恰好满足出点和入点匹配的性质&#xff0c;所以可以拆点然后对应连边&#xff0c;这样跑最…

.net测试篇之单元测试/集成测试神器Autofixture

autofixture简介有了单元测试框架加上Moq(后面我们会用单独章节来介绍moq),可以说测试问题基上都能搞定了.然而有了AutoFixture对单元测试来说可以说是如虎添翼,AutoFixture并且它能与moq,rhinomock等框架结合,对单元测试带来的便捷性,可维护性和扩展性更是难以言表,只有用用了…

杜教筛入门详解

杜教筛入门 前置知识 迪利克雷卷积&#xff08;*&#xff09;&#xff1a; 先介绍三个重要的函数&#xff1a; 元函数ϵ(n)[n1]\epsilon(n) [n 1]ϵ(n)[n1] 原函数可以看成是迪利克雷卷积里的单位元&#xff0c;即(ϵ∗f)(n)f(n)(\epsilon * f)(n) f(n)(ϵ∗f)(n)f(n)&am…