全 WA 球助
查看原帖
全 WA 球助
675466
zzx0102楼主2023/12/10 20:08
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define mk_p make_pair
#define fi first
#define se second
const int N = 100010; int n, in[N * 2], rt, d[N], v[N * 2], cnt, son[N], dep[N], dp[N][20], a[N], b[N], Q, m, ans[N * 5], cnt1[N], cnt2[N];
int h[N], to[N * 2], nxt[N * 2], idx; void add(int a, int b) {to[++idx] = b; nxt[idx] = h[a]; h[a] = idx;}
struct Query {
	int l, r, o, id; Query() {}
	Query(int a, int b, int c, int d) {l = a, r = b, o = c, id = d;}
} q[N * 20];
bool cmp(Query a, Query b) {return (in[a.l] != in[b.l]) ? (in[a.l] < in[b.l]) : ((in[a.l] & 1) ? a.r < b.r : a.r > b.r);}
void dfs(int u, int fa) {
	dp[u][0] = fa; dep[u] = dep[fa] + 1, son[u] = 1; d[u] = ++cnt;
	for(int i = h[u]; i; i = nxt[i]) {int v = to[i]; if(v == fa) continue; dfs(v, u); son[u] += son[v];}
}
void RMQ() {for(int i = 1; i < 20; i++) for(int j = 1; j <= n; j++) dp[j][i] = dp[dp[j][i - 1]][i - 1];}
pair<int, int> ask(int x) {
	if(x == rt) return mk_p(1, n); int delta = dep[rt] - dep[x] - 1;
	int u = rt; for(int i = 0; i < 20; i++) if(delta & (1 << i)) u = dp[u][i];// cout << "u = " << u << '\n';
	if(dp[u][0] != x) return mk_p(d[x], d[x] + son[x] - 1); return mk_p(d[u] + son[u], d[u] + n - 1);
}
signed main() {
	ios::sync_with_stdio(0); cin >> n >> Q; rt = 1; for(int i = 1; i <= n; i++) cin >> a[i], b[i] = a[i]; int sum = 0;
	int tot = unique(b + 1, b + 1 + n) - b - 1; for(int i = 1; i <= n; i++) a[i] = lower_bound(b + 1, b + 1 + tot, a[i]) - b;
	for(int i = 1; i < n; i++) {int u, v; cin >> u >> v; add(u, v); add(v, u);}
	dfs(1, 0); RMQ(); int j = 0;
	for(int i = 1; i <= n; i++) v[d[i]] = v[d[i] + n] = a[i];
	for(int i = 0; i < Q; i++) {
		int o, x; cin >> o >> x; if(o == 1) rt = x;
		else {
			int y; cin >> y; pair<int, int> p1 = ask(x), p2 = ask(y); int a = p1.fi, b = p1.se, c = p2.fi, d = p2.se;
//			cout << a << ' ' << b << ' ' << c << ' ' << d << '\n';
			++j; q[++m] = Query(b, d, 1, j); q[++m] = Query(a - 1, c - 1, 1, j);
			q[++m] = Query(b, c - 1, -1, j); q[++m] = Query(a - 1, d, -1, j);
		}
	}
	for(int i = 1; i <= m; i++) if(q[i].l > q[i].r) swap(q[i].l, q[i].r);
	int len = 2 * n / sqrt(m); for(int i = 1; i <= 2 * n; i++) in[i] = (i + len - 1) / len;
	sort(q + 1, q + 1 + m, cmp);
	for(int i = 1, l = 1, r = 0; i <= m; i++) {
		while(l > q[i].l) cnt1[v[l]]--, sum -= cnt2[v[l--]];
        while(r < q[i].r) cnt2[v[++r]]++, sum += cnt1[v[r]];
        while(l < q[i].l) cnt1[v[++l]]++, sum += cnt2[v[l]];
        while(r > q[i].r) cnt2[v[r]]--, sum -= cnt1[v[r--]];
        ans[q[i].id] += sum * q[i].o;
	}
	for(int i = 1; i <= j; i++) cout << ans[i] << '\n';
    return 0;
}
2023/12/10 20:08
加载中...