为什么 WA 成了 6 分?
查看原帖
为什么 WA 成了 6 分?
448887
cancan123456楼主2022/5/10 06:53

离线,然后树状数组二维数点。

#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 300000;
struct Edge {
	int v, next;
} edge[2 * N];
int head[N];
int cnt;
void add_edge(int u, int v) {
	cnt++;
	edge[cnt].v = v;
	edge[cnt].next = head[u];
	head[u] = cnt;
}
int dfn[N], dfncnt, size[N], dep[N];
void dfs(int u, int fa) {
	size[u] = 1;
	dfn[u] = ++dfncnt;
	for (int v, i = head[u]; i != 0; i = edge[i].next) {
		v = edge[i].v;
		if (v != fa) {
			dep[v] = dep[u] + 1;
			dfs(v, u);
			size[u] += size[v];
		}
	}
}
int n;
int c[N];
int lowbit(int x) {
	return x & - x;
}
void add(int x, int v) {
	if (x == 0) {
		c[x] += v;
	} else {
		while (x <= n) {
			c[x] += v;
			x += lowbit(x);
		}
	}
}
int query(int x) {
	int v = 0;
	while (x > 0) {
		v += c[x];
		x -= lowbit(x);
	}
	return v + c[0];
}
struct Point {
	int x, y, w;
} point[N];
bool operator < (const Point & a, const Point & b) {
	return a.y < b.y;
}
struct Query {
	int x, y1, y2, id;
} q[2 * N];
int qcnt;
bool operator < (const Query & a, const Query & b) {
	return a.x < b.x;
}
int ans[N];
int min(int a, int b) {
	return a < b ? a : b;
}
signed main() {
	int m;
	scanf("%d %d", &n, &m);
	for (int u, v, i = 1; i < n; i++) {
		scanf("%d %d", &u, &v);
		add_edge(u, v);
		add_edge(v, u);
	}
	dfs(1, 0);
	for (int i = 1; i <= n; i++) {
		point[i] = (Point) {dfn[i], dep[i], size[i] - 1};
	}
	for (int p, k, i = 1; i <= m; i++) {
		scanf("%d %d", &p, &k);
		ans[i] += min(dep[p], k) * (size[p] - 1);
		q[++qcnt] = (Query) {dfn[p], dep[p] + 1, min(dep[p] + k, n), -i};
		q[++qcnt] = (Query) {dfn[p] + size[p] - 1, dep[p] + 1, min(dep[p] + k, n), i};
	}
	sort(point + 1, point + n + 1);
	sort(q + 1, q + qcnt + 1);
	for (int i = 1, now = 1; i <= n; i++) {
		add(point[i].y, point[i].w);
		while (q[now].x <= point[i].x && now <= qcnt) {
			int id = q[now].id;
			if (id < 0) {
				ans[-id] -= query(q[now].y2) - query(q[now].y1 - 1);
			} else {
				ans[id] += query(q[now].y2) - query(q[now].y1 - 1);
			}
			now++;
		}
	}
	for (int i = 1; i <= m; i++) {
		printf("%lld\n", ans[i]);
	}
	return 0;
}
2022/5/10 06:53
加载中...