我老差了, 根本看不懂代码, 能大概理解线段树合并的概念做法, 但就是看不懂代码。关于下面这份代码, 能不能答我几个问题啊www
#include <bits/stdc++.h>
namespace mystd {
inline int read() {
int w = 1, q = 0;
char ch = ' ';
while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if (ch == '-') w = -1, ch = getchar();
while (ch >= '0' && ch <= '9') q = q * 10 + ch - '0', ch = getchar();
return w * q;
}
inline void write(int x) {
if (x < 0) {
x = ~(x - 1);
putchar('-');
}
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}
}
using namespace std;
using namespace mystd;
const int maxn = 1e5 + 100;
struct edge { int to, nxt; } e[maxn << 1];
struct segtree { int ls, rs, vl; } tr[maxn << 5];
int n, cnt, tot, len, head[maxn], w[maxn], tp[maxn], ans[maxn], rt[maxn];
void add_edge(int u, int v) {
e[++tot] = (edge) { v, head[u] };
head[u] = tot;
}
void pushup(int x) { tr[x].vl = tr[tr[x].ls].vl + tr[tr[x].rs].vl; }
int update(int l, int r, int p, int x) {//1, len, w[i], rt[i]
if (!x) x = ++cnt;
if (l == r) { tr[x].vl++; return x; }//vl为多少个比他大的
int mid = (l + r) >> 1;
if (p <= mid) tr[x].ls = update(l, mid, p, tr[x].ls);
else tr[x].rs = update(mid + 1, r, p, tr[x].rs);
pushup(x); return x;
}
int query(int l, int r, int s, int t, int x) {
if (s <= l && r <= t) return tr[x].vl;
int mid = (l + r) >> 1, res = 0;
if (s <= mid) res += query(l, mid, s, t, tr[x].ls);
if (t > mid) res += query(mid + 1, r, s, t, tr[x].rs);
return res;
}
int merge(int l, int r, int x, int y) {
if (!x || !y) return x + y;
if (l == r) { tr[x].vl += tr[y].vl; return x; }
int mid = (l + r) >> 1;
tr[x].ls = merge(l, mid, tr[x].ls, tr[y].ls);
tr[x].rs = merge(mid + 1, r, tr[x].rs, tr[y].rs);
pushup(x); return x;
}
void calc(int u, int f) {
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (v == f) continue;
calc(v, u);
rt[u] = merge(1, len, rt[u], rt[v]);
}
ans[u] = query(1, len, w[u] + 1, len, rt[u]);
}
int main() {
n = read();
for (int i = 1; i <= n; i++) tp[i] = w[i] = read();
sort(tp + 1, tp + n + 1);
len = unique(tp + 1, tp + n + 1) - tp - 1;
for (int i = 1; i <= n; i++) {
w[i] = lower_bound(tp + 1, tp + len + 1, w[i]) - tp;
rt[i] = update(1, len, w[i], rt[i]);
}
for (int i = 2, x; i <= n; i++) {
x = read(), add_edge(i, x), add_edge(x, i);
}
calc(1, 0);
for (int i = 1; i <= n; i++) {
write(ans[i]);
puts("");
}
return 0;
}
1.为啥update函数里l == r时+啊??凭什么加啊..为什么他一定会比一个数大啊?
2.一个节点的线段树上每一个节点维护的是什么啊??
3.queryQ了个啥啊..
同学的代码.