你说得对,但是 Wa on Master test #11
查看原帖
你说得对,但是 Wa on Master test #11
666796
Rainsleep楼主2023/10/24 11:13

()过不去了翻了眼评论区。

大家的写法都非常的神仙,不过我的代码里并没有出现()什么维护正反两颗线段树的东西我并没用到。

啊?不会我这是错解吧。

#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;
}

拜一拜。

2023/10/24 11:13
加载中...