萌新刚学树剖,想知道为什么前11个TLE,最后一个WA
查看原帖
萌新刚学树剖,想知道为什么前11个TLE,最后一个WA
833124
BIOS楼主2024/7/22 18:34

感觉像是犯了什么抽风错误才会TLE,能不能有佬粗略看一下?

#include <iostream>
#include <cstring>
using namespace std;
const int N = 2e5 + 5, M = 4e5 + 5;
int h[N], e[M], ne[M], ew[M], w[N], top[N], nw[N], sz[N], son[N], fa[N], id[N], dep[N];
int idx, n, x, m, u, v, c, cnt;
string op;
void add(int a, int b, int c)
{
    e[idx] = b, ne[idx] = h[a], ew[idx] = c, h[a] = idx++;
}
struct node
{
    int l, r, add, sum, maxv, minv;
} tr[N << 2];
struct Edge
{
    int u, v, w;
} edge[N];
void dfs1(int u, int father, int d)
{
    dep[u] = d, fa[u] = father, sz[u] = 1;
    for (int i = h[u]; ~i; i = ne[i])
    {
        int j = e[i];
        if (j == father)
        {
            w[u] = ew[i];
            continue;
        }
        dfs1(j, u, d + 1), sz[u] += sz[j];
        if (sz[son[u]] < sz[j])
            son[u] = j;
    }
}
void dfs2(int u, int t)
{
    top[u] = t, id[u] = ++cnt, nw[cnt] = w[u];
    if (!son[u])
        return;
    dfs2(son[u], t);
    for (int i = h[u]; ~i; i = ne[i])
    {
        int j = e[i];
        if (j == fa[u] || j == son[u])
            continue;
        dfs2(j, j);
    }
}
void pushup(int u)
{
    tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
    tr[u].maxv = max(tr[u << 1].maxv, tr[u << 1 | 1].maxv);
    tr[u].minv = min(tr[u << 1].minv, tr[u << 1 | 1].minv);
}
void pushdown(int u)
{
    if (tr[u].add)
    {
        int a, b;
        tr[u << 1].add ^= 1, tr[u << 1 | 1].add ^= 1;

        tr[u << 1].sum = -tr[u << 1].sum;
        a = tr[u << 1].maxv, b = tr[u << 1].minv;
        tr[u << 1].maxv = -b, tr[u << 1].minv = -a;

        tr[u << 1 | 1].sum = -tr[u << 1 | 1].sum;
        a = tr[u << 1 | 1].maxv, b = tr[u << 1 | 1].minv;
        tr[u << 1 | 1].maxv = -b, tr[u << 1 | 1].minv = -a;
    }
}
void build(int u, int l, int r)
{
    if (l == r)
        return tr[u] = {l, l, 0, nw[l], nw[l], nw[l]}, void();
    tr[u].l = l, tr[u].r = r;
    int mid = l + r >> 1;
    build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
    pushup(u);
}
void modify(int u, int x, int k)
{
    if (tr[u].l == tr[u].r && tr[u].l == x)
        return tr[u].sum = tr[u].maxv = tr[u].minv = k, tr[u].add = 0, void();
    int mid = tr[u].l + tr[u].r >> 1;
    pushdown(u);
    if (x <= mid)
        modify(u << 1, x, k);
    else
        modify(u << 1 | 1, x, k);
    pushup(u);
}
void modify(int u, int l, int r, int k)
{
    if (l <= tr[u].l && tr[u].r <= r)
    {
        tr[u].add ^= 1, tr[u].sum = -tr[u].sum;
        int a = tr[u].maxv, b = tr[u].minv;
        tr[u].maxv = -b, tr[u].minv = -a;
        return;
    }
    int mid = tr[u].l + tr[u].r >> 1;
    pushdown(u);
    if (l <= mid)
        modify(u << 1, l, r, k);
    if (r > mid)
        modify(u << 1 | 1, l, r, k);
    pushup(u);
}
void modify_path(int u, int v)
{
    while (top[u] != top[v])
    {
        if (dep[top[u]] < dep[top[v]])
            swap(u, v);
        modify(1, id[top[u]], id[u], 0), u = fa[top[u]];
    }
    if (dep[u] < dep[v])
        swap(u, v);
    if (dep[v] < dep[u])
        modify(1, id[v] + 1, id[u], 0);
}
int query1(int u, int l, int r)
{
    if (l <= tr[u].l && tr[u].r <= r)
        return tr[u].sum;
    int res = 0, mid = tr[u].l + tr[u].r >> 1;
    pushdown(u);
    if (l <= mid)
        res += query1(u << 1, l, r);
    if (r > mid)
        res += query1(u << 1 | 1, l, r);
    return res;
}
int query2(int u, int l, int r)
{
    if (l <= tr[u].l && tr[u].r <= r)
        return tr[u].maxv;
    int res = -1e9, mid = tr[u].l + tr[u].r >> 1;
    pushdown(u);
    if (l <= mid)
        res = max(res, query2(u << 1, l, r));
    if (r > mid)
        res = max(res, query2(u << 1 | 1, l, r));
    return res;
}
int query3(int u, int l, int r)
{
    if (l <= tr[u].l && tr[u].r <= r)
        return tr[u].minv;
    int res = 1e9, mid = tr[u].l + tr[u].r >> 1;
    pushdown(u);
    if (l <= mid)
        res = min(res, query3(u << 1, l, r));
    if (r > mid)
        res = min(res, query3(u << 1 | 1, l, r));
    return res;
}
int query_path(int u, int v, int op)
{
    int res1 = 0, res2 = -1e9, res3 = 1e9;
    while (top[u] != top[v])
    {
        if (dep[top[u]] < dep[top[v]])
            swap(u, v);
        if (op == 1)
            res1 += query1(1, id[top[u]], id[u]);
        else if (op == 2)
            res2 = max(res2, query2(1, id[top[u]], id[u]));
        else
            res3 = min(res3, query3(1, id[top[u]], id[u]));
    }
    if (dep[u] < dep[v])
        swap(u, v);
    if (dep[v] < dep[u])
    {
        if (op == 1)
            res1 += query1(1, id[v] + 1, id[u]);
        else if (op == 2)
            res2 = max(res2, query2(1, id[v] + 1, id[u]));
        else
            res3 = min(res3, query3(1, id[v] + 1, id[u]));
    }
    if (op == 1)
        return res1;
    else if (op == 2)
        return res2;
    else
        return res3;
}
int 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 >> u >> v >> c, ++u, ++v, add(u, v, c), add(v, u, c), edge[i] = {u, v, c};
    cin >> m, dfs1(1, -1, 1), dfs2(1, 1), build(1, 1, n);
    while (m--)
    {
        cin >> op;
        if (op == "C")
        {
            cin >> x >> c, u = edge[x].u, v = edge[x].v;
            if (dep[u] < dep[v])
                modify(1, id[v], c);
            else
                modify(1, id[u], c);
        }
        else if (op == "N")
            cin >> u >> v, ++u, ++v, modify_path(u, v);
        else if (op == "SUM")
            cin >> u >> v, ++u, ++v, cout << query_path(u, v, 1) << "\n";
        else if (op == "MAX")
            cin >> u >> v, ++u, ++v, cout << query_path(u, v, 2) << "\n";
        else
            cin >> u >> v, ++u, ++v, cout << query_path(u, v, 3) << "\n";
    }
}
2024/7/22 18:34
加载中...