这份代码开O2AC了,不开O2 10分?
查看原帖
这份代码开O2AC了,不开O2 10分?
490978
小超手123楼主2023/4/8 15:05
#include<bits/stdc++.h>
#define N 4000006
#define int long long
using namespace std;
int n, m, tot;
int t[N], dep[N], fa[N], siz[N], son[N], dfn[N], a[N], top[N];
vector<int>p[N];
void dfs1(int x, int father) {
    dep[x] = dep[father] + 1;
    fa[x] = father;
    siz[x] = 1;
    int maxson = -1;
    for(int i = 0; i < p[x].size(); i++) {
        int y = p[x][i];
        if(y == father) continue;
        dfs1(y, x);
        siz[x] += siz[y];
        if(siz[y] > maxson) {
            maxson = siz[y];
            son[x] = y;
		}
	}
}
void dfs2(int x, int topf) {
    dfn[x] = ++tot;
    a[tot] = t[x];
    top[x] = topf;
    if(son[x] == 0) return;
    dfs2(son[x], topf);
    for(int i = 0; i < p[x].size(); i++) {
        int y = p[x][i];
        if(dfn[y] == 0) dfs2(y, y);
	}
}
struct node {
    int maxx, minn, lmax, rmax, tag;
    //maxx:最大值 minn:最小值 lmax:从左往右的最大价值  rmax:从右往左的最大价值
    friend node operator + (node a, node b) {
        node s;
        s.maxx = max(a.maxx, b.maxx);
        s.minn = min(a.minn, b.minn);
        s.lmax = max(max(a.lmax, b.lmax), b.maxx - a.minn);
        s.rmax = max(max(a.rmax, b.rmax), a.maxx - b.minn);
        return s;
	}
}c[N];
void pushup(int u) {
    c[u] = c[u * 2] + c[u * 2 + 1];
}
void build(int u, int L, int R) {
    if(L == R) {
        c[u].maxx = a[L];
        c[u].minn = a[L];
        return;
	}
	int mid = (L + R) / 2;
	build(u * 2, L, mid);
	build(u * 2 + 1, mid + 1, R);
	pushup(u);
}
void maketag(int u, int x) {
    c[u].maxx += x;
    c[u].minn += x;
    c[u].tag += x;
}
void pushdown(int u) {
    maketag(u * 2, c[u].tag);
    maketag(u * 2 + 1, c[u].tag);
    c[u].tag = 0;
}
bool OutofRange(int L, int R, int l, int r) { return r < L || R < l; }
bool InRange(int L, int R, int l, int r) { return l <= L && R <= r; }
void update(int u, int L, int R, int l, int r, int k) {
    if(OutofRange(L, R, l, r)) return;
    if(InRange(L, R, l, r)) {
        maketag(u, k);
        return;
	}
	pushdown(u);
	int mid = (L + R) / 2;
	update(u * 2, L, mid, l, r, k);
	update(u * 2 + 1, mid + 1, R, l, r, k);
	pushup(u);
}
node query(int u, int L, int R, int l, int r) {
    if(OutofRange(L, R, l, r)) {
        node S;
        S.maxx = -1e15;
        S.minn = 1e15;
        S.lmax = S.rmax = S.tag = 0;
        return S;
	} 
    if(InRange(L, R, l, r)) return c[u];
    pushdown(u);
    int mid = (L + R) / 2; 
    return query(u * 2, L, mid, l, r) + query(u * 2 + 1, mid + 1, R, l, r);
} 
signed main() {
    cin >> n;
    for(int i = 1; i <= n; i++) 
        cin >> t[i];
	for(int i = 1; i <= n - 1; i++) {
	    int u, v;
	    cin >> u >> v;
	    p[u].push_back(v);
	    p[v].push_back(u);
	}
	dfs1(1, 0);
	dfs2(1, 1);
	build(1, 1, n);
	cin >> m;
	while(m--) {
	    int x, y, k, X, Y;
	    cin >> x >> y >> k;
	    X = x, Y = y;
	    node L, R;
	    L.lmax = L.rmax = 0;
	    L.maxx = -1e15;
	    L.minn = 1e15;
	    R = L;
		while(top[x] != top[y]) {
		    if(dep[top[x]] < dep[top[y]]) { //跳y
			    node S = query(1, 1, n, dfn[top[y]], dfn[y]);
				R = S + R;
				y = fa[top[y]];
			}
			else { //跳x
			    node S = query(1, 1, n, dfn[top[x]], dfn[x]);
			    L = S + L;
			    x = fa[top[x]];
			}
		}
		if(dep[x] < dep[y]) { //y在x的下面  
		    node S = query(1, 1, n, dfn[x], dfn[y]); 
		    R = S + R;
		}
		else {//x在y的下面 
		    node S = query(1, 1, n, dfn[y], dfn[x]);
		    L = S + L;
		}
		int ans = max(max(L.rmax, R.lmax), R.maxx - L.minn);
		if(ans < 0) cout << "0" << endl;
		else cout << ans << endl;
		x = X, y = Y; 
		while(top[x] != top[y]) {
		    if(dep[top[x]] < dep[top[y]]) swap(x, y);
		    update(1, 1, n, dfn[top[x]], dfn[x], k);
		    x = fa[top[x]];
		}
		if(dep[x] > dep[y]) swap(x, y);
		update(1, 1, n, dfn[x], dfn[y], k);
	}
    return 0;
}
2023/4/8 15:05
加载中...