感觉像是犯了什么抽风错误才会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";
}
}