()过不去了翻了眼评论区。
大家的写法都非常的神仙,不过我的代码里并没有出现()什么维护正反两颗线段树的东西我并没用到。
啊?不会我这是错解吧。
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast", "inline", "-ffast-math")
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
// #define int long long
#define x first
#define y second
const int N = 1e5 + 10, del = 1e4 + 1, und = -del;
int h[N], idx = -1, n, Q, ts = 0;
int sz[N], fa[N], son[N], id[N], dfn[N], top[N], dep[N], w[N], dfns[N];
struct E {
int v, nxt;
} e[N << 1];
class Tree {
private :
struct Node {
int lmax, rmax, res, s, C;
} tr[N << 2];
inline Node merge(Node l, Node r) {
if(l.C == und) return r;
if(r.C == und) return l;
return (Node){max(l.lmax, l.s + r.lmax), max(r.rmax, r.s + l.rmax),
max({l.res, r.res, l.rmax + r.lmax}), l.s + r.s, del
};
}
inline void pushdown(int u, int L, int R) {
auto& t = tr[u], &l = tr[u << 1], &r = tr[u << 1 | 1];
if(t.C != del) {
int mid = L + R >> 1, sl = (mid - L + 1) * t.C, sr = (R - (mid + 1) + 1) * t.C;
if(t.C) l = (Node){sl, sl, sl, sl, t.C}, r = (Node){sr, sr, sr, sr, t.C};
else l = (Node){t.C, t.C, t.C, t.C, t.C}, r = (Node){t.C, t.C, t.C, t.C, t.C};
t.C = del;
}
return ;
}
public :
inline void build(int u, int l, int r) {
if(l == r) {
tr[u].lmax = tr[u].rmax = tr[u].s = tr[u].res = w[dfns[l]], tr[u].C = del;
return ;
}
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r), tr[u] = merge(tr[u << 1], tr[u << 1 | 1]);
return ;
}
inline void update(int u, int l, int r, int Ql, int Qr, int c) {
if(Ql <= l and Qr >= r) {
int s = (r - l + 1) * c;
if(c) tr[u] = {s, s, s, s, c};
else tr[u] = {c, c, c, c, c};
return ;
}
int mid = l + r >> 1; pushdown(u, l, r);
if(Ql <= mid) update(u << 1, l, mid, Ql, Qr, c);
if(Qr > mid) update(u << 1 | 1, mid + 1, r, Ql, Qr, c);
tr[u] = merge(tr[u << 1], tr[u << 1 | 1]); return ;
}
inline void update_tr(int u, int v, int c) {
if(dep[u] < dep[v]) swap(u, v);
while(top[u] != top[v]) {
if(dep[top[u]] < dep[top[v]]) swap(u, v);
// clog << "update " << top[u] << ' ' << u << '\n';
update(1, 1, n, dfn[top[u]], dfn[u], c);
u = fa[top[u]];
}
if(dep[v] > dep[u]) swap(u, v);
// clog << "update " << v << ' ' << u << '\n';
update(1, 1, n, dfn[v], dfn[u], c); return ;
}
inline Node query(int u, int l, int r, int Ql, int Qr) {
if(Ql <= l and Qr >= r) return tr[u];
int mid = l + r >> 1; pushdown(u, l, r);
Node ret = {und, und, und, und, und};
if(Ql <= mid) ret = merge(ret, query(u << 1, l, mid, Ql, Qr));
if(Qr > mid) ret = merge(ret, query(u << 1 | 1, mid + 1, r, Ql, Qr));
tr[u] = merge(tr[u << 1], tr[u << 1 | 1]);
return ret;
}
inline int query_tr(int u, int v) {
if(dep[u] < dep[v]) swap(u, v);
Node ret = {und, und, und, und, und};
while(top[u] != top[v]) {
if(dep[top[u]] < dep[top[v]]) swap(u, v);
ret = merge(ret, query(1, 1, n, dfn[top[u]], dfn[u]));
// cout << "Qpath " << top[u] << ' ' << u << '\n';
// cout << ret.lmax << ' ' << ret.rmax << ' ' << ret.s << ' ' << ret.res << ' ' << ret.C << '\n';
u = fa[top[u]];
}
if(dep[v] > dep[u]) swap(u, v);
ret = merge(ret, query(1, 1, n, dfn[v], dfn[u]));
// cout << "Qpath " << v << ' ' << u << '\n';
// cout << ret.lmax << ' ' << ret.rmax << ' ' << ret.s << ' ' << ret.res << ' ' << ret.C << '\n';
return ret.res;
}
} T;
inline void link(int x, int y) {
e[++ idx] = {y, h[x]}, h[x] = idx; return ;
}
inline void dfs1(int u, int pa) {
sz[u] = 1, dep[u] = dep[pa] + 1, fa[u] = pa;
for(int i(h[u]); ~i; i = e[i].nxt) {
int v = e[i].v;
if(v == pa) continue ;
dfs1(v, u), sz[u] += sz[v];
if(sz[v] > sz[son[u]]) son[u] = v;
}
return ;
}
inline void dfs2(int u, int t) {
top[u] = t, dfn[u] = ++ ts, dfns[ts] = u;
if(son[u]) dfs2(son[u], t);
for(int i(h[u]); ~i; i = e[i].nxt) {
int v = e[i].v;
if(v == fa[u] or v == son[u]) continue ;
dfs2(v, v);
}
return ;
}
signed main() {
ios :: sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n;
memset(h, -1, sizeof h);
for(int i(1); i <= n; ++ i) cin >> w[i];
for(int i(1), u, v; i < n; ++ i) cin >> u >> v, link(u, v), link(v, u);
dfs1(1, 0), dfs2(1, 1), T.build(1, 1, n);
// for(int i(1); i <= n; ++ i) cout << son[i] << ' ' << top[i] << '\n';
cin >> Q;
for(int i(1); i <= n; ++ i) cout << dfn[i] << ' ';
cout << '\n';
for(int op, u, v, c; Q --; ) {
cin >> op >> u >> v;
if(op & 1) cout << max(T.query_tr(u, v), 0) << '\n';
else {
cin >> c, T.update_tr(u, v, c);
}
}
return 0;
}
拜一拜。