QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#473528#1163. Another Tree Queries Problemaqz180321WA 87ms45356kbC++145.8kb2024-07-12 08:32:412024-07-12 08:32:41

Judging History

你现在查看的是最新测评结果

  • [2024-07-12 08:32:41]
  • 评测
  • 测评结果:WA
  • 用时:87ms
  • 内存:45356kb
  • [2024-07-12 08:32:41]
  • 提交

answer

#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector> 

const int N = 2e5 + 10;
int n, q;
std::vector < int > edge[N];

int dfn[N], dfntot, id[N];
int dep[N], son[N], size[N], fa[N], top[N], st[30][N];

struct seg1 {
	int sum[N << 2], lazya[N << 2], lazyb[N << 2];
	
	void add (int pos, int l, int r, int a, int b) {
		sum[pos] += (l + r) * a * (r - l + 1) / 2;
		sum[pos] += (r - l + 1) * b;
		lazya[pos] += a;
		lazyb[pos] += b;
	}
	
	void update (int pos) {
		sum[pos] = sum[pos << 1] + sum[pos << 1 | 1];
	}
	
	void push (int pos, int l, int r) {
		if (lazya[pos] || lazyb[pos]) {
			int mid = (l + r) >> 1;
			add (pos << 1, l, mid, lazya[pos], lazyb[pos]);
			add (pos << 1 | 1, mid + 1, r, lazya[pos], lazyb[pos]);
			lazya[pos] = lazyb[pos] = 0;
		}
	}
	
	void build (int pos, int l, int r) {
		sum[pos] = lazya[pos] = lazyb[pos] = 0;
		if (l == r) return ;
		int mid = (l + r) >> 1;
		build (pos << 1, l, mid);
		build (pos << 1 | 1, mid + 1, r);
	}
	
	void modify (int pos, int l, int r, int x, int y, int a, int b) {
		if (x <= l && r <= y) {
			add (pos, l, r, a, b);
			return ;
		}
		push (pos, l, r);
		int mid = (l + r) >> 1;
		if (x <= mid) modify (pos << 1, l, mid, x, y, a, b);
		if (y >= mid + 1) modify (pos << 1 | 1, mid + 1, r, x, y, a, b);
		update (pos); 
	}
	
	int query (int pos, int l, int r, int x, int y) {
		if (x <= l && r <= y) return sum[pos];
		push (pos, l, r);
		int mid = (l + r) >> 1, ans = 0;
		if (x <= mid) ans += query (pos << 1, l, mid, x, y);
		if (y >= mid + 1) ans += query (pos << 1 | 1, mid + 1, r, x, y);
		return ans;
	}
} tr1;

struct seg2 {
	int sz[N << 2], sum[N << 2];
	int lazy[N << 2];
	
	void add (int pos, int k) {
		sum[pos] += sz[pos] * k;
		lazy[pos] += k;
	}
	
	void push (int pos) {
		if (lazy[pos]) {
			add (pos << 1, lazy[pos]);
			add (pos << 1 | 1, lazy[pos]);
			lazy[pos] = 0;
		}
	} 
	
	void update (int pos) {
		sz[pos] = sz[pos << 1] + sz[pos << 1 | 1];
		sum[pos] = sum[pos << 1] + sum[pos << 1 | 1];
	}
	
	void build (int pos, int l, int r) {
		sum[pos] = lazy[pos] = 0;
		if (l == r) {
			sz[pos] = size[id[l]];
			return ;
		}
		int mid = (l + r) >> 1;
		build (pos << 1, l, mid);
		build (pos << 1 | 1, mid + 1, r);
		update (pos);
	}
	
	void modify (int pos, int l, int r, int x, int y, int k) {
		if (x <= l && r <= y) {
			add (pos, k);
			return ;
		}
		push (pos);
		int mid = (l + r) >> 1;
		if (x <= mid) modify (pos << 1, l, mid, x, y, k);
		if (y >= mid + 1) modify (pos << 1 | 1, mid + 1, r, x, y, k);
		update (pos);
	}
	
	int query (int pos, int l, int r, int x, int y) {
		if (x <= l && r <= y) return sum[pos];
		push (pos);
		int mid = (l + r) >> 1, ans = 0;
		if (x <= mid) ans += query (pos << 1, l, mid, x, y);
		if (y >= mid + 1) ans += query (pos << 1 | 1, mid + 1, r, x, y);
		return ans;
	}
} tr2;

void dfs1 (int x, int father) {
	fa[x] = father;
	st[0][x] = father;
	dep[x] = dep[father] + 1;
	size[x] = 1;
	for (int i = 1; i <= 25; i++)
		st[i][x] = st[i - 1][st[i - 1][x]];
	for (auto v : edge[x]) {
		if (v == father) continue;
		dfs1 (v, x);
		size[x] += size[v];
		if (size[son[x]] < size[v]) son[x] = v;
	}
}

void dfs2 (int x, int y) {
	top[x] = y;
	dfn[x] = ++dfntot;
	id[dfntot] = x;
	if (son[x]) dfs2 (son[x], y);
	for (auto v : edge[x]) {
		if (dfn[v]) continue;
		dfs2 (v, v);
	}
}

int lca (int x, int y) {
	if (dep[x] < dep[y]) std::swap(x, y);
	int k = dep[x] - dep[y];
	for (int j = 0; k; j++, k >>= 1) 
		if (k & 1) x = st[j][x];
	if (x == y) return x;
	for (int i = 20; i >= 0; i--) 
		if (st[i][x] != st[i][y]) {
			x = st[i][x];
			y = st[i][y];
		}
	return st[0][x];
}

int depsum[N], asum, adepsum;

void rootupd (int u, int cnt) {
	asum += cnt;
	while (u != 0) {
		tr1.modify (1, 1, n, dfn[top[u]], dfn[u], 0, cnt);
		u = fa[top[u]];
	}
	return ;
}

void subtree (int u, int k) {
	adepsum += k * (depsum[dfn[u] + size[u] - 1] - depsum[dfn[u] - 1]);
	tr2.modify (1, 1, n, dfn[u], dfn[u] + size[u] - 1, k);
	rootupd (fa[u], k * size[u]);
}

int jump (int u, int k) {
	for (int j = 0; k; k >>= 1, j++)
		if (k & 1) u = st[j][u];
	return u;
} 

void work1 (int u, int v) {
	if (u == v) {
		subtree(1, 1);
		return ;
	}
	int k = lca(u, v);
	if (k == v) subtree(1, 1), subtree(jump(u, dep[u] - dep[v]), -1);
	else subtree(v, 1);
		
}

void work2 (int u, int v) {
	int lfs = 0, ris = 0;
	while (top[u] != top[v]) {
		if (dep[top[u]] < dep[top[v]])
			std::swap(u, v), std::swap(lfs, ris);
		tr1.modify (1, 1, n, dfn[top[u]], dfn[u], -1, dfn[u] + 1 + lfs);
		lfs += dfn[top[u]] - dfn[u] + 1;
		adepsum += (depsum[dfn[u]] - depsum[dfn[top[u]] - 1]);
		u = fa[top[u]]; 
	} 
	if (dfn[u] < dfn[v])
		std::swap(u, v), std::swap(lfs, ris);
	adepsum += (depsum[dfn[u]] - depsum[dfn[v] - 1]);
	tr1.modify (1, 1, n, dfn[v], dfn[u], -1, dfn[u] + 1 + lfs);
	tr1.modify (1, 1, n, dfn[v], dfn[v], 0, ris);
	rootupd (fa[v], lfs + ris + dep[u] - dep[v] + 1) ;
}

int getsum (int u) {
	int ans = adepsum;
	while (u != 0) {
		ans = ans - 2 * (tr1.query (1, 1, n, dfn[top[u]], dfn[u]) + tr2.query (1, 1, n, dfn[top[u]], dfn[u]));
		ans = ans + (dfn[u] - dfn[top[u]] + 1) * asum;
		u = fa[top[u]];
	}
	return ans;
}

int main() {
	scanf("%d", &n);
	for (int i = 1, u, v; i < n; i++) {
		scanf("%d%d", &u, &v);
		edge[u].push_back(v);
		edge[v].push_back(u);
	}
	dfs1 (1, 0);
	dfs2 (1, 1);
	for (int i = 1; i <= n; i++)
		depsum[i] = depsum[i - 1] + dep[id[i]];
	tr1.build (1, 1, n);
	tr2.build (1, 1, n);
	scanf("%d", &q);
	for (int i = 1, opt, u, v; i <= q; i++) {
		scanf("%d", &opt);
		if (opt == 1) {
			scanf("%d%d", &u, &v);
			work1 (u, v);
		} else if (opt == 2) {
			scanf("%d%d", &u, &v);
			work2 (u, v);
		} else if (opt == 3) {
			scanf("%d", &u);
			printf("%d\n", getsum(u));
		}
	}
	return 0;
}

详细

Test #1:

score: 100
Accepted
time: 0ms
memory: 45356kb

input:

5
4 2
2 5
1 5
1 3
5
2 2 4
3 4
2 1 5
2 5 5
3 2

output:

1
5

result:

ok 2 number(s): "1 5"

Test #2:

score: -100
Wrong Answer
time: 87ms
memory: 43516kb

input:

200
171 114
50 183
28 68
67 152
139 125
67 55
50 98
106 71
46 42
157 165
42 49
113 12
81 145
105 13
38 96
34 156
24 17
21 191
135 54
174 116
177 157
123 71
95 130
135 193
150 129
25 190
96 93
188 173
90 160
86 187
20 132
199 75
59 195
189 24
40 68
163 83
25 13
73 33
59 50
154 19
146 21
151 67
89 69
...

output:

494
400
457
1385
1884
1416
2226
2203
3871
3325
3117
3185
3939
3259
3976
5911
4662
4305
6051
7241
5053
5604
5672
4470
9919
10695
7937
8199
8817
9273
14712
13462
13719
12816
8919
11413
11985
13362
12308
12550
15716
16464
19693
17802
12887
15969
12793
16320
12887
18792
18270
23839
18644
26089
15449
250...

result:

wrong answer 1st numbers differ - expected: '826', found: '494'