重金(5 RMB)悬赏树剖
  • 板块灌水区
  • 楼主maniac_duckpear
  • 当前回复4
  • 已保存回复4
  • 发布时间2021/10/1 09:11
  • 上次更新2023/11/4 05:16:21
查看原帖
重金(5 RMB)悬赏树剖
239321
maniac_duckpear楼主2021/10/1 09:11

(只支持微信付款)

大概就是区间最大子段和加上树剖,但是我太弱了根本调不出来。

就是这道题

(不要问我为什么没有提交记录,这只是某人的小号)

#include<iostream>
using namespace std;
const int INF = 2147483647;
int n, m, cnt, point[1000005], a[1000005], id[1000005], fa[1000005], top[1000005], siz[1000005], deep[1000005], son[1000005], head[1000005], tot;
struct road
{
    int y, nex;
}s[1000005];
void add(int i, int j)
{
    s[++tot].y = j, s[tot].nex = head[i];
    head[i] = tot;
}
struct node
{
    int sum, l, r, m, tag;
}tree[1000005];
void modify(int now, int l, int r, int w)
{
    tree[now].sum = w * (r - l + 1);
    tree[now].l = tree[now].r = tree[now].m = max(0, tree[now].sum);
    tree[now].tag = w;
}
void push_up(int now)
{
    tree[now].l = max(tree[now * 2].l, tree[now * 2].sum + tree[now * 2 + 1].l);
    tree[now].r = max(tree[now * 2 + 1].r, tree[now * 2 + 1].sum + tree[now * 2].r);
    tree[now].m = max(tree[now * 2].r + tree[now * 2 + 1].l, max(tree[now * 2].m, tree[now * 2 + 1].m));
    tree[now].sum = tree[now * 2].sum + tree[now * 2 + 1].sum;
}
void push_down(int now, int l, int r)
{
    if (tree[now].tag == INF)
        return;
    int mid = (l + r) / 2;
    modify(now * 2, l, mid, tree[now].tag);
    modify(now * 2 + 1, mid + 1, r, tree[now].tag);
    tree[now].tag = INF;
}
void build(int now, int l, int r)
{
    if (l == r)
    {
        tree[now].sum = tree[now].l = tree[now].r = tree[now].m = max(a[l], 0);
        tree[now].tag = INF;
        return;
    }
    int mid = (l + r) / 2;
    build(now * 2, l, mid);
    build(now * 2 + 1, mid + 1, r);
    push_up(now);
    tree[now].tag = INF;
}
void update(int now, int l, int r, int x, int y, int w)
{
    if (l > y || r < x)
        return;
    if (x <= l && r <= y)
    {
        modify(now, l, r, w);
        return;
    }
    push_down(now, l, r);
    int mid = (l + r) / 2;
    update(now * 2, l, mid, x, y, w);
    update(now * 2 + 1, mid + 1, r, x, y, w);
    push_up(now);
}
node query(int now, int l, int r, int x, int y)
{
    if (x <= l && r <= y)
        return tree[now];
    int mid = (l + r) / 2;
    push_down(now, l, r);
    if (x > mid)
        return query(now * 2 + 1, mid + 1, r, x, y);
    else if (y <= mid)
        return query(now * 2, l, mid, x, y);
    else
    {
        node tmpa = query(now * 2, l, mid, x, y), tmpb = query(now * 2 + 1, mid + 1, r, x, y);
        node ans = { tmpa.sum + tmpb.sum,max(tmpa.l,tmpa.sum + tmpb.l),max(tmpb.r,tmpb.sum + tmpa.r),max(max(tmpa.m,tmpb.m),tmpa.r + tmpb.l),0 };
        return ans;
    }
}
void dfs1(int now, int father)
{
    int nowson = -1;
    deep[now] = deep[father] + 1;
    fa[now] = father;
    siz[now] = 1;
    for (int i = head[now]; i; i = s[i].nex)
    {
        int y = s[i].y;
        if (y == father)
            continue;
        dfs1(y, now);
        siz[now] += siz[y];
        if (siz[y] > nowson)
            nowson = siz[y], son[now] = y;
    }
}
void dfs2(int now, int topf)
{
    id[now] = ++cnt;
    a[cnt] = point[now];
    top[now] = topf;
    if (!son[now])
        return;
    dfs2(son[now], topf);
    for (int i = head[now]; i; i = s[i].nex)
    {
        int y = s[i].y;
        if (y == fa[now] || y == son[now])
            continue;
        dfs2(y, y);
    }
}
void res1(int x, int y, int w)
{
    while (top[x] != top[y])
    {
        if (deep[top[x]] < deep[top[y]])
            swap(x, y);
        update(1, 1, n, id[top[x]], id[x], w);
        x = fa[top[x]];
    }
    if (deep[x] > deep[y])
        swap(x, y);
    update(1, 1, n, id[x], id[y], w);
}
node res2(int x, int y)
{
    node l = { 0,-INF,-INF,-INF,0 }, r = { 0,-INF,-INF,-INF,0 };
    while (top[x] != top[y])
    {
        if (deep[top[x]] > deep[top[y]])
        {
            node ano = query(1, 1, n, id[top[x]], id[x]);
            x = fa[top[x]];
            l = { l.sum + ano.sum,max(l.l,l.sum + ano.l),max(ano.r,ano.sum + l.r),max(max(l.m,ano.m),l.r + ano.l),0 };
        }
        else
        {
            node ano = query(1, 1, n, id[top[y]], id[y]);
            y = fa[top[y]];
            r = { r.sum + ano.sum,max(r.l,r.sum + ano.l),max(ano.r,ano.sum + r.r),max(max(r.m,ano.m),r.r + ano.l),0 };
        }
    }
    if (deep[x] > deep[y])
    {
        node ano = query(1, 1, n, id[y], id[x]);
        l = { l.sum + ano.sum,max(l.l,l.sum + ano.l),max(ano.r,ano.sum + l.r),max(max(l.m,ano.m),l.r + ano.l),0 };
    }
    else
    {
        node ano = query(1, 1, n, id[x], id[y]);
        r = { r.sum + ano.sum,max(r.l,r.sum + ano.l),max(ano.r,ano.sum + r.r),max(max(r.m,ano.m),r.r + ano.l),0 };
    }
    swap(l.l, l.r);
    return { l.sum + r.sum,max(l.l,l.sum + r.l),max(r.r,r.sum + l.r),max(max(l.m,r.m),l.r + r.l),0 };
}
signed main()
{
    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> point[i];
    for (int i = 1; i < n; i++)
    {
        int u, v;
        cin >> u >> v;
        add(u, v);
        add(v, u);
    }
    dfs1(1, 0);
    dfs2(1, 1);
    build(1, 1, n);
    cin >> m;
    for (int i = 1; i <= m; i++)
    {
        int op, u, v, w;
        cin >> op;
        if (op == 1)
        {
            cin >> u >> v;
            cout << max(res2(u, v).m, 0) << endl;
        }
        else
            cin >> u >> v >> w, res1(u, v, w);
    }
    return 0;
}
2021/10/1 09:11
加载中...