!->?->!!->?!?->????->………………
查看原帖
!->?->!!->?!?->????->………………
218311
Sham_Sleep楼主2022/9/6 16:46

虽然但是,用的是树剖+重构树,但一直不知道wa在哪里了,改了很久了,求哪位dalao康康。

某一知名比赛的原题,题目是我做这道题的心路历程(雾

#include <bits/stdc++.h>
#define Inf 9223372036854775800
#define ll long long 
using namespace std;
const ll N = 1e6 + 5;

ll min(ll a, ll b) {return a < b ? a : b;}
ll max(ll a, ll b) {return a > b ? a : b;}

struct T {
	ll val, l, r;
} t[N << 3];

struct edge {
	ll to, w, pre;
} g[N << 1];

struct line {
	ll a, b, w;
} L[N << 2];

ll n, m, q, cnt, now;
ll oder[N], b[N], p[N], F[N];
ll v[N], size[N], son[N], fa[N], top[N], id[N], dep[N], RANK[N], val[N];

void add(ll a, ll b, ll w) {
	g[++cnt].pre = v[a];
	v[a] = cnt;
	g[cnt].to = b;
	g[cnt].w = w;
	return ;
}

bool cmp(line a, line b) {return a.w > b.w;}

ll findfa(ll x) {return F[x] == x ? x : F[x] = findfa(F[x]);}

void dfs_1(ll u, ll f, ll d) {
	size[u] = 1;
	dep[u] = d;
	fa[u] = f;
	for(ll i = v[u]; i; i = g[i].pre) {
		ll p = g[i].to;
		if(fa[u] == p) continue;
		val[p] = g[i].w;
		dfs_1(p, u, d + 1);
		size[u] += size[p];
		if(size[p] > size[son[u]])
			son[u] = p;
	}
	return ;
}

void dfs_2(ll u, ll tp) {
	top[u] = tp;
	id[u] = ++now;
	RANK[now] = u;
	if(son[u]) {
		top[son[u]] = top[u];
		dfs_2(son[u], tp);
	}
	else return ;
	
	for(ll i = v[u]; i; i = g[i].pre) {
		ll p = g[i].to;
		if(p == fa[u] || p == son[u])
			continue;
		dfs_2(p, p);
	}
	return ;
}

void update(ll rt) {
	t[rt].val = min(t[rt << 1].val, t[rt << 1 | 1].val);
	return ;
}

void build(ll rt, ll l, ll r) {
	if(l == r) {
		t[rt].l = t[rt].r = l;
		t[rt].val = val[RANK[l]];
		return ;
	}
	t[rt].l = l, t[rt].r = r;
	ll mid = (l + r) >> 1;
	build(rt << 1, l, mid);
	build(rt << 1 | 1, mid + 1, r);
	update(rt);
	return ;
}

ll Que(ll l, ll r, ll rt) {
	if(l > r) swap(l, r);
	if(t[rt].l >= l && t[rt].r <= r)
		return t[rt].val;
	ll mid = (t[rt].l + t[rt].r) >> 1, ans = Inf;
	if(mid >= l)
		ans = min(ans, Que(l, r, rt << 1));
	if(mid < r)
		ans = min(ans, Que(l, r, rt << 1 | 1));
	return ans;
}

ll lca(ll x, ll y) {
	ll fx = top[x], fy = top[y], ans = Inf;
	while(fx != fy) {
		if(dep[fx] < dep[fy])
			swap(x, y), swap(fx, fy);
		ans = min(ans, Que(id[fx], id[x], 1));
		x = fa[fx], fx = top[x];
	}
	if(dep[x] > dep[y])
		swap(x, y);
	if(x != y) ans = min(ans, Que(id[x] + 1, id[y], 1));
	return ans;
}

int main() {
	cin >> n >> m >> q;
	for(ll i = 1; i <= n; ++i)
		F[i] = i;
	for(ll i = 1; i <= n; ++i)
		scanf("%lld", &oder[i]);
	for(ll i = 1; i <= n; ++i)
		scanf("%lld", &b[i]);
	for(ll i = 1; i <= m; ++i)
		scanf("%lld %lld %lld", &L[i].a, &L[i].b, &L[i].w);
	for(ll i = 1;  i <= q; ++i)
		scanf("%lld", &p[i]);
	cnt = m;
	for(ll i = 2; i <= q; ++i) {
		L[++cnt].a = p[i];
		L[cnt].b = p[1];
		L[cnt].w = Inf;
	}
	std :: sort(L + 1, L + 1 + cnt, cmp);
	ll x = 0, y = 1;
	while(x < n - 1 && y <= cnt) {
		ll f1 = findfa(F[L[y].a]);
		ll f2 = findfa(F[L[y].b]);
		if(f1 != f2) {
			F[f1] = f2;
			add(L[y].a, L[y].b, L[y].w);
			add(L[y].b, L[y].a, L[y].w);
			++x;
		}
		++y;
	}
	
	dfs_1(1, 0, 1);
	dfs_2(1, 1);
	build(1, 1, n);
	
	ll have = 0;
	if(b[oder[1]] > 0)
		have += b[oder[1]];
	else	
		puts("0");
	
	for(ll i = 2; i <= n; ++i) {
		if(b[oder[i]] > 0)
			have += b[oder[i]];
		else {
			ll o = lca(oder[i - 1], oder[i]);
			have = min(have, o);
			printf("%lld\n", min(have, -b[oder[i]]));
			have = max(have + b[oder[i]], 0);
		}
	}
	return 0;
}
  
 20分
2022/9/6 16:46
加载中...