文章目录
- **入门讲解**
- **[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;
}