30pts求调
查看原帖
30pts求调
379768
Wzhone楼主2023/10/20 10:37
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
const ll MAXN = 3e4 + 10;
const ll INF = 0x3f3f3f3f;
vector<ll> edge[MAXN];
ll hson[MAXN], son[MAXN], value[MAXN], dfn[MAXN], siz[MAXN], dp[MAXN], tp[MAXN];
ll fa[MAXN];
ll _in[MAXN], _out[MAXN];
ll cnt;

struct zkw
{
    ll tre[MAXN << 4]; ll M;

    void build(ll n)
    {
        M = 1;
        while (M < n)
            M <<= 1;
    }

    void add(ll now, ll value)
    {
        ll p = M + now;
        tre[p] = value;
        while(p >>= 1) tre[p] = max(tre[p << 1], tre[p << 1 | 1]);
    }

    ll fin(ll l, ll r)
    {
        if(l > r) swap(l,r);
        l = l - 1 + M, r = r + 1 + M;
        ll maxx = -INF;
        for (; l ^ r ^ 1; l >>= 1, r >>= 1)
        {
            if (~l & 1)
                maxx = max(maxx, tre[l ^ 1]);
            if (r & 1)
                maxx = max(maxx, tre[r ^ 1]);
        }
        return maxx;
    }
} zkwmax;

struct zkw2
{
    ll tre[MAXN << 4]; ll M;

    void build(ll n)
    {
        M = 1;
        while(M <= n) M <<= 1;
    }

    void add(ll now, ll value)
    {
        ll p = M + now;
        tre[p] = value;
        while(p >>= 1) tre[p] = tre[p << 1] + tre[p << 1 | 1];
    }

    ll fin(ll l, ll r)
    {
        if(l > r) swap(l,r);
        l = l - 1 + M, r = r + 1 + M;
        ll maxx = 0;
        for (; l ^ r ^ 1; l >>= 1, r >>= 1)
        {
            if (~l & 1)
                maxx += tre[l ^ 1];
            if (r & 1)
                maxx += tre[r ^ 1];
        }
        return maxx;
    }
} zkwsum;

void dfs1(ll now, ll f, ll dep)
{
    fa[now] = f;
    siz[now] = 1;
    dp[now] = dep;
    ll maxsiz = -1;
    for (ll son : edge[now])
    {
        if (son == fa[now])
            continue;
        dfs1(son, now, dep + 1);
        siz[now] += siz[son];
        if (siz[son] > maxsiz)
            hson[now] = son, maxsiz = siz[son];
    }
    if (!hson[now])
        hson[now] = -1;
}

void dfs2(ll now, ll top)
{
    dfn[now] = ++cnt;
    _in[now] = cnt;
    tp[now] = top;
    if (hson[now] != -1)
        dfs2(hson[now], top);
    for (ll son : edge[now])
    {
        if (son == fa[now] || son == hson[now])
            continue;
        dfs2(son, son);
    }
    _out[now] = cnt;
}

void inline connect(ll a, ll b)
{
    edge[a].pb(b);
    edge[b].pb(a);
}

ll qmax(ll u, ll v)
{
    ll ans = -INF;
    while(tp[u] != tp[v]){
        if(dp[tp[u]] < dp[tp[v]]) swap(u,v);
        ans = max(ans,zkwmax.fin(dfn[tp[u]],dfn[u]));
        u = fa[tp[u]];
    }
    if(dp[u] < dp[v]) ans = max(ans,zkwmax.fin(dfn[u],dfn[v]));
    else ans = max(ans,zkwmax.fin(dfn[v],dfn[u]));
    return ans;
}

ll qsum(ll u, ll v)
{
    ll ans = 0;
    while(tp[u] != tp[v]){
        if(dp[tp[u]] < dp[tp[v]]) swap(u,v);
        ans += zkwsum.fin(dfn[tp[u]],dfn[u]);
        u = fa[tp[u]];
    }
    if(dp[u] < dp[v]) ans += zkwsum.fin(dfn[u],dfn[v]);
    else ans += zkwsum.fin(dfn[v],dfn[u]);
    return ans;
}

int main()
{
    ll n,m;
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    for (ll i = 1; i < n; i++)
    {
        ll x, y;
        cin >> x >> y;
        connect(x, y);
    }

    for (ll i = 1; i <= n; i++)
    {
        cin >> value[i];
    }

    dfs1(1, 0, 1);
    dfs2(1, 1);
    zkwmax.build(n);
    zkwsum.build(n);
    for (ll i = 1; i <= n; i++)
    {
        zkwmax.add(i, value[i]);
        zkwsum.add(i, value[i]);
    }
    cin >> m;
    for (ll i = 1; i <= m; i++)
    {
        string a;
        cin >> a;
        if (a == "CHANGE")
        {
            ll u, t;
            cin >> u >> t;
            value[u] = t;
            zkwmax.add(u, value[u]);
            zkwsum.add(u, value[u]);
        }
        else if (a == "QMAX")
        {
            ll u, v;
            cin >> u >> v;
            cout << qmax(u, v) << "\n";
        }
        else if (a == "QSUM")
        {
            ll u, v;
            cin >> u >> v;
            cout << qsum(u, v) << "\n";
        }
    }
}

2023/10/20 10:37
加载中...