MnZn 初学树剖求调,1AC其他RE过不了样例QaQ
查看原帖
MnZn 初学树剖求调,1AC其他RE过不了样例QaQ
224558
JackMerryYoung楼主2023/7/10 22:11

Rt.

#include <bits/stdc++.h>
#define ll long long
using namespace std;

ll N, M, value[200005];

struct Edge {
    ll nxt, to, w;
} edge[400005];

ll cnt, head[200005];

void add(ll u, ll v, ll w)
{
    ++ cnt;
    edge[cnt].nxt = head[u];
    edge[cnt].to = v;
    edge[cnt].w = w;
    head[u] = cnt;
}

ll sz[200005], heavyson[200005], father[200005], depth[200005];

void dfs1(ll u, ll fa, ll dep)
{
    sz[u] = 1;
    father[u] = fa;
    depth[u] = dep;
    for(ll i = head[u]; i; i = edge[i].nxt)
    {
        ll v = edge[i].to;
        if(v == fa) continue;
        dfs1(v, u, dep + 1);
        value[v] = edge[i].w;
        sz[u] += sz[v];
        if(sz[v] > sz[heavyson[u]]) heavyson[u] = v;
    }
}

ll dfncnt, dfn[200005], linktop[200005], newvalue[200005];
ll edgetodfn[200005];

void dfs2(ll u, ll lktp)
{
    dfn[u] = ++ dfncnt;
    linktop[u] = lktp;
    newvalue[dfn[u]] = value[u];
    if(!heavyson[u]) return;
    dfs2(heavyson[u], lktp);
    for(ll i = head[u]; i; i = edge[i].nxt)
    {
        ll v = edge[i].to;
        if(v == father[u] || v == heavyson[u]) continue;
        dfs2(v, v);
    }
}

#define lson ((p << 1) | 0)
#define rson ((p << 1) | 1)
#define mid ((l + r) >> 1)

struct SegmentTree {
    ll sum, max, min, lazytag_inv;
} T[(200005 << 2) + 5];

void merge(ll p)
{
    T[p].sum = T[lson].sum + T[rson].sum;
    T[p].max = max(T[lson].max, T[rson].max);
    T[p].min = min(T[lson].min, T[rson].min);
}

void pushdown(ll l, ll r, ll p)
{
    ll lmax = T[lson].max, lmin = T[lson].min, rmax = T[rson].max, rmin = T[rson].min;
    T[lson].sum = -T[lson].sum, T[rson].sum = -T[rson].sum, T[lson].max = -lmin, T[lson].min = -lmax, T[rson].max = -rmin, T[rson].min = -rmax, T[lson].lazytag_inv = !T[lson].lazytag_inv, T[rson].lazytag_inv = !T[rson].lazytag_inv;
    T[p].lazytag_inv = 0;
}

void build(ll l, ll r, ll p)
{
    if(l == r)
    {
        T[p].sum = T[p].max = T[p].min = newvalue[l];
        return;
    }

    build(l, mid, lson); build(mid + 1, r, rson);
    merge(p);
}

void modify_let(ll l, ll r, ll x, ll p, ll val)
{
    if(l == r)
    {
        T[p].sum = T[p].max = T[p].min = val;
        return;
    }

    if(T[p].lazytag_inv) pushdown(l, r, p);
    if(x <= mid) modify_let(l, mid, x, lson, val);
    if(x >= mid + 1) modify_let(mid + 1, r, x, rson, val);
    merge(p);
}

void modify_inv(ll l, ll r, ll lll, ll rrr, ll p)
{
    if(lll <= l && rrr >= r)
    {
        ll pmax = T[p].max, pmin = T[p].min;
        T[p].lazytag_inv = !T[p].lazytag_inv, T[p].sum = -T[p].sum, T[p].max = -pmin, T[p].min = -pmax;
        return;
    }

    if(T[p].lazytag_inv) pushdown(l, r, p);
    if(lll <= mid) modify_let(l, mid, lll, rrr, lson);
    if(rrr >= mid + 1) modify_let(mid + 1, r, lll, rrr, rson);
    merge(p);
}

void modify_inv_simplepath(ll x, ll y)
{
    while(linktop[x] != linktop[y])
    {
        if(depth[linktop[x]] < depth[linktop[y]]) swap(x, y);
        modify_inv(1, N, dfn[linktop[x]], dfn[x], 1);
        x = father[linktop[x]];
    }

    if(depth[x] > depth[y]) swap(x, y);
    if(x != y) modify_inv(1, N, dfn[x] + 1, dfn[y], 1);
}

ll query_sum(ll l, ll r, ll lll, ll rrr, ll p)
{
    if(lll <= l && rrr >= r)
        return T[p].sum;
    
    ll res = 0;
    if(T[p].lazytag_inv) pushdown(l, r, p);
    if(lll <= mid) res += query_sum(l, mid, lll, rrr, lson);
    if(rrr >= mid + 1) res += query_sum(mid + 1, r, lll, rrr, rson);
    return res;
}

ll query_max(ll l, ll r, ll lll, ll rrr, ll p)
{
    if(lll <= l && rrr >= r)
        return T[p].max;
    
    ll res = LLONG_MIN;
    if(T[p].lazytag_inv) pushdown(l, r, p);
    if(lll <= mid) res = max(res, query_max(l, mid, lll, rrr, lson));
    if(rrr >= mid + 1) res = max(res, query_max(mid + 1, r, lll, rrr, rson));
    return res;
}

ll query_min(ll l, ll r, ll lll, ll rrr, ll p)
{
    if(lll <= l && rrr >= r)
        return T[p].min;
    
    ll res = LLONG_MAX;
    if(T[p].lazytag_inv) pushdown(l, r, p);
    if(lll <= mid) res = min(res, query_min(l, mid, lll, rrr, lson));
    if(rrr >= mid + 1) res = min(res, query_min(mid + 1, r, lll, rrr, rson));
    return res;
}

ll query_sum_simplepath(ll x, ll y)
{
    ll res = 0;
    while(linktop[x] != linktop[y])
    {
        if(depth[linktop[x]] < depth[linktop[y]]) swap(x, y);
        res += query_sum(1, N, dfn[linktop[x]], dfn[x], 1);
        x = father[linktop[x]];
    }

    if(depth[x] > depth[y]) swap(x, y);
    if(x != y) res += query_sum(1, N, dfn[x] + 1, dfn[y], 1);
    return res;
}

ll query_max_simplepath(ll x, ll y)
{
    ll res = LLONG_MIN;
    while(linktop[x] != linktop[y])
    {
        if(depth[linktop[x]] < depth[linktop[y]]) swap(x, y);
        res = max(res, query_max(1, N, dfn[linktop[x]], dfn[x], 1));
        x = father[linktop[x]];
    }

    if(depth[x] > depth[y]) swap(x, y);
    if(x != y) res = max(res, query_max(1, N, dfn[x] + 1, dfn[y], 1));
    return res;
}

ll query_min_simplepath(ll x, ll y)
{
    ll res = LLONG_MAX;
    while(linktop[x] != linktop[y])
    {
        if(depth[linktop[x]] < depth[linktop[y]]) swap(x, y);
        res = min(res, query_min(1, N, dfn[linktop[x]], dfn[x], 1));
        x = father[linktop[x]];
    }

    if(depth[x] > depth[y]) swap(x, y);
    if(x != y) res = min(res, query_min(1, N, dfn[x] + 1, dfn[y] , 1));
    return res;
}

pair<ll, ll> tmpedge[200005];

signed main()
{
    cin >> N;
    for(ll i = 1; i < N; ++ i)
    {
        ll a, b, c;
        cin >> a >> b >> c;
        ++ a, ++ b;
        add(a, b, c); add(b, a, c);
        tmpedge[i] = make_pair(a, b);
    }

    dfs1(1, 1, 1);
    dfs2(1, 1);
    build(1, N, 1);
    cin >> M;
    for(ll i = 1; i <= M; ++ i)
    {
        string opr;
        cin >> opr;
        if(opr == "C")
        {
            ll E, W, tmp = 0;
            cin >> E >> W;
            if(depth[tmpedge[E].first] > depth[tmpedge[E].second]) tmp = tmpedge[E].first;
            else tmp = tmpedge[E].second;
            modify_let(1, N, dfn[tmp], 1, W);
        }
        if(opr == "N")
        {
            ll U, V;
            cin >> U >> V;
            ++ U, ++ V;
            modify_inv_simplepath(U, V);
        }
        if(opr == "SUM")
        {
            ll U, V;
            cin >> U >> V;
            ++ U, ++ V;
            cout << query_sum_simplepath(U, V) << endl;
        }
        if(opr == "MAX")
        {
            ll U, V;
            cin >> U >> V;
            ++ U, ++ V;
            cout << query_max_simplepath(U, V) << endl;
        }
        if(opr == "MIN")
        {
            ll U, V;
            cin >> U >> V;
            ++ U, ++ V;
            cout << query_min_simplepath(U, V) << endl;
        }
    }
    return 0;
}
2023/7/10 22:11
加载中...