本地可以过样例,但是交上去全是 WA,求大佬看看
查看原帖
本地可以过样例,但是交上去全是 WA,求大佬看看
822420
DGME楼主2023/8/30 21:03

下载第一个测试点数据,发现竟然是样例----

#include <bits/stdc++.h>

using namespace std;

constexpr int N = 200010;
constexpr int inf = 1e9;
vector<int> adj[N];
int f[N][2],g[N][2],w[N];
int sz[N],dfn[N],dep[N],idx;
int a[N],fa[N],son[N],top[N],End[N];

struct Val{
    int mat[2][2];
    Val() {
        mat[0][0] = mat[1][1] = 0;
        mat[0][1] = mat[1][0] = -inf;
    }
};
struct Info{
    int l,r;Val s;
};
Val operator+(const Val &a,const Val &b){
    Val c;
    c.mat[0][0] = c.mat[1][1] = -inf;
    for(int i = 0;i < 2;i ++ )
        for(int j = 0;j < 2;j ++ )
            for(int k = 0;k < 2;k ++ )
                c.mat[i][j] = max(c.mat[i][j],a.mat[i][k] + b.mat[k][j]);
    return c;
}
Info op(Info a){
    int u = w[a.l];
    a.s.mat[1][1] = -inf;
    a.s.mat[1][0] = g[u][1];
    a.s.mat[0][1] = a.s.mat[0][0] = g[u][0];
    return a;
}
struct SegTree
{
    int n;
    vector<Info> tr;
    SegTree(int n):n(n){
        tr.resize(n * 4 + 1),build(1,1,n);
    }
    void build(int u,int l,int r){
        tr[u].l = l,tr[u].r = r;
        if(l != r){
            int mid = (l + r) / 2;
            build(u * 2,l,mid);
            build(u * 2 + 1,mid + 1,r);
            pushup(u);
        } else {
            tr[u].s.mat[1][1] = -inf;
            tr[u].s.mat[1][0] = g[w[l]][1]; 
            tr[u].s.mat[0][0] = tr[u].s.mat[0][1] = g[w[l]][0];
        }
    }
    void modify(int u,int l,int r){
        if(tr[u].l < l || tr[u].r > r){
            int mid = (tr[u].l  + tr[u].r) / 2;
            if(l <= mid) modify(u * 2,l,r);
            if(r > mid) modify(u * 2 + 1,l,r);
            pushup(u);
        }
        else tr[u] = op(tr[u]);
    }
    Val ask(int u,int l,int r){
        if(tr[u].l >= l && tr[u].r <= r)
            return tr[u].s;
        int mid = (tr[u].l + tr[u].r ) / 2;
        Val ans;
        if(l <= mid) ans = ask(u * 2,l,r);
        if(r > mid) ans = ans + ask(u * 2 + 1,l,r);
        return ans; 
    }
    void pushup(int u){
        tr[u].s = tr[u * 2].s + tr[u * 2 + 1].s;
    }
};

void dfs1(int u,int v) {
    fa[u] = v,sz[u] = 1;
    f[u][1] = a[u];
    for(auto x : adj[u]) {
        if(x == v) continue;
        dfs1(x,u);sz[u] += sz[x];
        if(sz[son[u]] < sz[x])
            son[u] = x;
        f[u][1] += f[x][0];
        f[u][0] += max(f[x][0],f[x][1]);
    }
}

void dfs2(int u,int v) {
    dfn[u] = ++ idx,top[u] = v;
    g[u][1] = a[u];
    if(!son[u]) {
        End[u] = u;
        return;
    }
    dfs2(son[u],v);
    End[u] = End[son[u]];
    for(auto x : adj[u]) {
        if(x != son[u] && x != fa[u]) {
            dfs2(x,x);
            g[u][0] += max(f[x][1],f[x][0]);
            g[u][1] += f[x][0];
        }
    }
}

int main() {
    int n,m;cin >> n >> m;
    for(int i = 1;i <= n;i ++ ) scanf("%d",a + i);
    for(int i = 0;i < n - 1;i ++ ) {
        int u,v;scanf("%d%d",&u,&v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    dfs1(1,0),dfs2(1,1);

    for(int i = 1;i <= n;i ++ )
        w[dfn[i]] = i;
    SegTree segtree(n);

    function<void(int,int)> update = [&](int u,int x) {
        g[u][1] += x - a[u];
        a[u] = x;
        while(u) {
            auto lst = segtree.ask(1,dfn[top[u]],dfn[End[u]]);
            segtree.modify(1,dfn[u],dfn[u]);
            auto now = segtree.ask(1,dfn[top[u]],dfn[End[u]]);
            u = fa[top[u]];
            g[u][0] += max(now.mat[0][0],now.mat[1][0]) - max(lst.mat[0][0],lst.mat[1][0]);
            g[u][1] += now.mat[0][0] - lst.mat[0][0];
        }
    };

    while(m -- ) {
        int p,x;scanf("%d%d",&p,&x);
        update(p,x);
        auto ans = segtree.ask(1,1,dfn[End[1]]).mat;
        printf("%d\n",max(ans[0][0],ans[1][0]));
    } 
}

2023/8/30 21:03
加载中...