树剖板题求调,只过了样例
查看原帖
树剖板题求调,只过了样例
526895
WYZ20030051楼主2024/4/18 21:06
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define ll long long
#define ull unsigned long long
#define int ll
int read()
{
    ll now = 0, nev = 1;
    char c = getchar();
    while (c < '0' || c > '9')
    {
        if (c == '-')
            nev = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9')
    {
        now = (now << 1) + (now << 3) + (c & 15);
        c = getchar();
    }
    return now * nev;
}
const int MAXN = 1e6 + 10;
const int INF = 1e18;
int n, q;
int a[MAXN];
int head[MAXN], tt = 0;
struct edge
{
    int to, nxt, dis;
} e[MAXN << 1];
void add(int x, int y, int z)
{
    e[++tt].nxt = head[x];
    head[x] = tt;
    e[tt].to = y;
    e[tt].dis = z;
}
struct node
{
    int x, y;
} id[MAXN];
int fa[MAXN], son[MAXN], siz[MAXN], dep[MAXN];
void dfs1(int u, int fat)
{
    dep[u] = dep[fat] + 1;
    siz[u] = 1;
    fa[u] = fat;
    for (int i = head[u]; i; i = e[i].nxt)
    {
        int v = e[i].to, w = e[i].dis;
        if (v == fat)
            continue;
        a[v] = w;
        dfs1(v, u);
        siz[u] += siz[v];
        if (siz[son[u]] < siz[v])
            son[u] = v;
    }
}
int top[MAXN], dfn[MAXN], seg[MAXN], num = 0;
void dfs2(int u, int topfa)
{
    top[u] = topfa;
    dfn[u] = ++num;
    seg[dfn[u]] = a[u];
    if (son[u])
    {
        dfs2(son[u], topfa);
        return;
    }
    for (int i = head[u]; i; i = e[i].nxt)
    {
        int v = e[i].to;
        if (v == fa[u] || v == son[u])
            continue;
        dfs2(v, v);
    }
}
struct tree
{
    int l, r;
    int sum;
    int mx, mn;
    int tag;
} tr[MAXN << 2];
void pushup(int k)
{
    tr[k].sum = tr[k << 1].sum + tr[k << 1 | 1].sum;
    tr[k].mx = max(tr[k << 1].mx, tr[k << 1 | 1].mx);
    tr[k].mn = min(tr[k << 1].mn, tr[k << 1 | 1].mn);
}
void build(int k, int l, int r)
{
    tr[k].l = l, tr[k].r = r;
    if (l == r)
    {
        tr[k].sum = tr[k].mx = tr[k].mn = seg[l];
        return;
    }
    int mid = (l + r) >> 1;
    build(k << 1, l, mid), build(k << 1 | 1, mid + 1, r);
    pushup(k);
}
void pushdown(int k)
{
    if (tr[k].tag)
    {
        tr[k << 1].sum = -tr[k << 1].sum;
        tr[k << 1 | 1].sum = -tr[k << 1 | 1].sum;
        int tmp1 = tr[k << 1].mx, tmp2 = tr[k << 1 | 1].mx;
        tr[k << 1].mx = -tr[k << 1].mn;
        tr[k << 1 | 1].mx = -tr[k << 1 | 1].mn;
        tr[k << 1].mn = -tmp1;
        tr[k << 1 | 1].mn = -tmp2;
        tr[k << 1].tag ^= 1;
        tr[k << 1 | 1].tag ^= 1;
        tr[k].tag ^= 1;
    }
}
void modefy1(int k, int x, int v)
{
    if (tr[k].l == tr[k].r)
    {
        tr[k].sum = tr[k].mx = tr[k].mn = v;
        return;
    }
    pushdown(k);
    int mid = (tr[k].l + tr[k].r) >> 1;
    if (x <= mid)
        modefy1(k << 1, x, v);
    else
        modefy1(k << 1 | 1, x, v);
    pushup(k);
}
void change(int x, int y, int z)
{
    if (fa[x] == y)
        modefy1(1, dfn[x], z);
    else
        modefy1(1, dfn[y], z);
}
void modefy2(int k, int l, int r)
{
    if (l <= tr[k].l && tr[k].r <= r)
    {
        int tmp = tr[k].mx;
        tr[k].sum = -tr[k].sum, tr[k].mx = -tr[k].mn, tr[k].mn = -tmp;
        tr[k].tag ^= 1;
        return;
    }
    pushdown(k);
    int mid = (tr[k].l + tr[k].r) >> 1;
    if (l <= mid)
        modefy2(k << 1, l, r);
    if (r > mid)
        modefy2(k << 1 | 1, l, r);
    pushup(k);
}
int query_sum(int k, int l, int r)
{
    if (l <= tr[k].l && tr[k].r <= r)
        return tr[k].sum;
    pushdown(k);
    int res = 0;
    int mid = (tr[k].l + tr[k].r) >> 1;
    if (l <= mid)
        res += query_sum(k << 1, l, r);
    if (r > mid)
        res += query_sum(k << 1 | 1, l, r);
    return res;
}
int query_max(int k, int l, int r)
{
    if (l <= tr[k].l && tr[k].r <= r)
        return tr[k].mx;
    pushdown(k);
    int res = -INF;
    int mid = (tr[k].l + tr[k].r) >> 1;
    if (l <= mid)
        res = max(res, query_sum(k << 1, l, r));
    if (r > mid)
        res = max(res, query_sum(k << 1 | 1, l, r));
    return res;
}
int query_min(int k, int l, int r)
{
    if (l <= tr[k].l && tr[k].r <= r)
        return tr[k].mn;
    pushdown(k);
    int res = INF;
    int mid = (tr[k].l + tr[k].r) >> 1;
    if (l <= mid)
        res = min(res, query_sum(k << 1, l, r));
    if (r > mid)
        res = min(res, query_sum(k << 1 | 1, l, r));
    return res;
}
void modefy(int x, int y)
{
    while (top[x] != top[y])
    {
        if (dep[top[x]] < dep[top[y]])
            swap(x, y);
        modefy2(1, dfn[top[x]], dfn[x]);
        x = fa[top[x]];
    }
    if (dep[x] > dep[y])
        swap(x, y);
    modefy2(1, dfn[x] + 1, dfn[y]);
}
int gsum(int x, int y)
{
    int res = 0;
    while (top[x] != top[y])
    {
        if (dep[top[x]] < dep[top[y]])
            swap(x, y);
        res += query_sum(1, dfn[top[x]], dfn[x]);
        x = fa[top[x]];
    }
    if (dep[x] > dep[y])
        swap(x, y);
    res += query_sum(1, dfn[x] + 1, dfn[y]);
    return res;
}
int gmax(int x, int y)
{
    int res = -INF;
    while (top[x] != top[y])
    {
        if (dep[top[x]] < dep[top[y]])
            swap(x, y);
        res = max(res, query_max(1, dfn[top[x]], dfn[x]));
        x = fa[top[x]];
    }
    if (dep[x] > dep[y])
        swap(x, y);
    res = max(res, query_max(1, dfn[x] + 1, dfn[y]));
    return res;
}
int gmin(int x, int y)
{
    int res = INF;
    while (top[x] != top[y])
    {
        if (dep[top[x]] < dep[top[y]])
            swap(x, y);
        res = min(res, query_min(1, dfn[top[x]], dfn[x]));
        x = fa[top[x]];
    }
    if (dep[x] > dep[y])
        swap(x, y);
    res = min(res, query_min(1, dfn[x] + 1, dfn[y]));
    return res;
}
signed main()
{
    n = read();
    for (int i = 1; i < n; i++)
    {
        int x = read(), y = read(), z = read();
        x++, y++;
        add(x, y, z), add(y, x, z);
        id[i].x = x, id[i].y = y;
    }
    dfs1(1, 0), dfs2(1, 0);
    build(1, 1, n);
    q = read();
    while (q--)
    {
        string op;
        cin >> op;
        int x = read(), y = read();
        x++, y++;
        if (op == "C")
        {
            x--, y--;
            change(id[x].x, id[x].y, y);
        }
        if (op == "N")
            modefy(x, y);
        if (op == "SUM")
            printf("%lld\n", gsum(x, y));
        if (op == "MAX")
            printf("%lld\n", gmax(x, y));
        if (op == "MIN")
            printf("%lld\n", gmin(x, y));
    }
    return 0;
}
2024/4/18 21:06
加载中...