求求 本地对拍了好久一直没错 SP给我WA了
查看原帖
求求 本地对拍了好久一直没错 SP给我WA了
116824
YingLi楼主2021/3/25 20:12

rt

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
#define maxn 100005
using namespace std;
typedef long long ll;
int read() {
	int x = 0, f = 1, ch = getchar();
	while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
	while(isdigit(ch)) x = (x << 1) + (x << 3) + ch - '0', ch = getchar();
	return x * f;
}

struct edge {int to, nxt;} e[maxn << 1];
int head[maxn], k = 0;
void add(int u, int v) {e[k] = {v, head[u]}; head[u] = k++;}

int n, q, a[maxn];
int fa[maxn], son[maxn], size[maxn], dep[maxn], top[maxn], dfn[maxn], tot = 0, id[maxn];
int t[maxn << 2], lx[maxn << 2], rx[maxn << 2], sum[maxn << 2], flag[maxn << 2];
struct node {int t, lx, rx, sum;};
node operator + (node a, node b) {
	node res = {0, 0, 0, 0};
	res.lx = max(a.lx, a.sum + b.lx);
	res.rx = max(b.rx, b.sum + a.rx);
	res.sum = a.sum + b.sum;
	res.t = max(a.t, b.t);
	res.t = max(res.t, a.rx + b.lx);
	res.t = max(res.t, max(res.lx, res.rx));
	return res;
}

struct SegT {
	void update(int p) {
		lx[p] = max(lx[p << 1], sum[p << 1] + lx[p << 1 | 1]);
		rx[p] = max(rx[p << 1 | 1], sum[p << 1 | 1] + rx[p << 1]);
		sum[p] = sum[p << 1] + sum[p << 1 | 1];
		t[p] = max(t[p << 1], t[p << 1 | 1]);
		t[p] = max(t[p], rx[p << 1] + lx[p << 1 | 1]);
		t[p] = max(t[p], max(lx[p], rx[p]));
	}
	
	void up(int p, int l, int r, int x) {
		t[p] = lx[p] = rx[p] = sum[p] = (r - l + 1) * x;
		if(t[p] < 0) t[p] = lx[p] = rx[p] = 0;
		flag[p] = x;
	}
	
	void build(int p, int l, int r) {
		if(l == r) {t[p] = lx[p] = rx[p] = sum[p] = a[id[l]]; if(t[p] < 0) t[p] = lx[p] = rx[p] = 0; return;}
		register int mid = l + r >> 1;
		build(p << 1, l, mid); build(p << 1 | 1, mid + 1, r);
		update(p);
	}
	
	void change(int p, int l, int r, int ls, int rs, int x) {
		if(ls <= l && r <= rs) {
//			printf("change %d %d\n", id[l], id[r]);
			if(x >= 0) t[p] = x, lx[p] = rx[p] = sum[p] = (r - l + 1) * x;
			else t[p] = lx[p] = rx[p] = 0, sum[p] = (r - l + 1) * x;
			flag[p] = x; return;
		}
		register int mid = l + r >> 1; 
		if(flag[p]) up(p << 1, l, mid, flag[p]), up(p << 1 | 1, mid + 1, r, flag[p]), flag[p] = 0;
		if(ls <= mid) change(p << 1, l, mid, ls, rs, x);
		if(rs > mid) change(p << 1 | 1, mid + 1, r, ls, rs, x);
		update(p);
	}
	
	node ask(int p, int l, int r, int ls, int rs) {
		if(ls <= l && r <= rs) return {t[p], lx[p], rx[p], sum[p]};
		register int mid = l + r >> 1; node ans = {0, 0, 0, 0};
		if(flag[p]) up(p << 1, l, mid, flag[p]), up(p << 1 | 1, mid + 1, r, flag[p]), flag[p] = 0;
		if(ls <= mid) ans = ans + ask(p << 1, l, mid, ls, rs);
		if(rs > mid) ans = ans + ask(p << 1 | 1, mid + 1, r, ls, rs);
		return ans;
	}
}T;

struct HLD {
	void dfs1(int u) {
		size[u] = 1;
		for(int i = head[u], v; ~i; i = e[i].nxt) if(e[i].to ^ fa[u]) {
			v = e[i].to; fa[v] = u; dep[v] = dep[u] + 1;
			dfs1(v); size[u] += size[v];
			if(size[v] > size[son[u]]) son[u] = v;
		}
	}
	
	void dfs2(int u, int tp) {
		dfn[u] = ++tot; top[u] = tp; id[tot] = u;
		if(son[u]) dfs2(son[u], tp);
		for(int i = head[u], v; ~i; i = e[i].nxt) 
			if((e[i].to ^ fa[u]) && (e[i].to ^ son[u])) dfs2(e[i].to, e[i].to);
	}
	
	void modify(int u, int v, int x) {
		while(top[u] != top[v]) {
			if(dep[top[u]] > dep[top[v]]) swap(u, v);
			T.change(1, 1, n, dfn[top[v]], dfn[v], x); v = fa[top[v]];
		}
		if(dep[u] > dep[v]) swap(u, v);
		T.change(1, 1, n, dfn[u], dfn[v], x);
	}
	
	int query(int u, int v) {
		node res1 = {0, 0, 0, 0}, res2 = {0, 0, 0, 0};
		while(top[u] != top[v]) {
			if(dep[top[u]] < dep[top[v]]) res1 = T.ask(1, 1, n, dfn[top[v]], dfn[v]) + res1, v = fa[top[v]];
			else res2 = T.ask(1, 1, n, dfn[top[u]], dfn[u]) + res2, u = fa[top[u]];
		}
//		printf("ask %d %d\n", u, v);
		if(dep[u] < dep[v]) res1 = T.ask(1, 1, n, dfn[u], dfn[v]) + res1;
		else res2 = T.ask(1, 1, n, dfn[v], dfn[u]) + res2;
		swap(res2.lx, res2.rx); 
		res1 = res2 + res1;
		return res1.t;
	}
}H;

signed main() {
//	freopen("in.txt", "r", stdin);
//	freopen("out.txt", "w", stdout);
	n = read(); memset(head, -1, sizeof head);
	for(int i = 1; i <= n; i++) a[i] = read();	
	for(int i = 1, u, v; i < n; i++) u = read(), v = read(), add(u, v), add(v, u);
	H.dfs1(1); H.dfs2(1, 1);
	T.build(1, 1, n);
	
	q = read();
	while(q--) {
		register int op = read(), l = read(), r = read(), x;
		if(op == 1) printf("%d\n", H.query(l, r));
		else x = read(), H.modify(l, r, x);
	}
	return 0;
}
2021/3/25 20:12
加载中...