虽然但是,用的是树剖+重构树,但一直不知道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分