线段树合并 Tle 求助
查看原帖
线段树合并 Tle 求助
195388
alvis楼主2021/9/6 20:46

不知道为什么T了。求助/kel

#include <bits/stdc++.h>
using namespace std;

const int N = 1e5+101, L = 1, R = 100000;
int n, idx, tot;
struct edge{
	int e, ne;
}g[N << 2];
struct tree {
	int ls, rs, ans, sum;
}t[N << 2];
int a[N], h[N], rt[N], ans[N];

void add(int a, int b) {
	g[idx].e = b;
	g[idx].ne = h[a];
	h[a] = idx ++;
}

void pushup(int q) {
	if(t[t[q].ls].sum < t[t[q].rs].sum) {
		t[q].ans = t[t[q].rs].ans; 
		t[q].sum = t[t[q].rs].sum;
	}
	if (t[t[q].rs].sum < t[t[q].ls].sum) {
		t[q].ans = t[t[q].ls].ans;
		t[q].sum = t[t[q].ls].sum;
	}
	if(t[t[q].rs].sum == t[t[q].ls].sum ){
		t[q].ans = t[t[q].ls].ans + t[t[q].rs].ans;
		t[q].sum = t[t[q].ls].sum;
	}
}

int insert(int q, int l, int r, int pos, int v) {
	if(!q) q = ++ tot;
	if(l == r) {
		t[q].sum += v;
		t[q].ans = l;
		return q;
	}
	int mid = l + r >> 1;
	if(pos <= mid) t[q].ls = insert(t[q].ls, l, mid, pos, v);
	else t[q].rs = insert(t[q].rs, mid+1, r, pos, v);
	pushup(q);
	return q;
}

int merge(int p, int q, int l, int r) {
	if(!p) return q;
	if(!q) return p;
	if(l == r) {
		t[p].ans = l;
		t[p].sum = t[p].sum + t[q].sum;
		return p;
	}
	int mid = (l + r) >> 1;
	t[p].ls = merge(t[p].ls, t[q].ls, l, mid);
	t[p].rs = merge(t[p].rs, t[q].rs, mid+1, r);
	pushup(p);
	return p;
}

void dfs(int u, int f) {
	for(int i = h[u];i != -1;i = g[i].ne) {
		int j = g[i].e;
		if(j == f) continue;
		dfs(j, u);
		rt[u] = merge(rt[u], rt[j], L, R); 
	}
	rt[u] = insert(rt[u], L, R, a[u], 1);
	ans[u] = t[rt[u]].ans;
}

int main() {
    ios::sync_with_stdio(false);cin.tie(0);
	memset(h, -1, sizeof h);
	cin >> n;
	for(int i = 1;i <= n;i ++) {
		cin >> a[i];
	}
	for(int i = 1, a, b;i < n;i ++ ){
		cin >> a >> b;
		add(a, b);
		add(b, a);
	}
	dfs(1, 0);
	for(int i = 1;i <= n;i ++) {
		cout << ans[i] << " ";
	}
	return 0;
} 
2021/9/6 20:46
加载中...