社区讨论

24pts,悬赏20rmb求调

P11324【MX-S7-T2】「SMOI-R2」Speaker参与者 3已保存回复 8

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
8 条
当前快照
1 份
快照标识符
@m416wcpx
此快照首次捕获于
2024/11/28 18:46
去年
此快照最后确认于
2025/11/04 13:44
4 个月前
查看原帖
rt,dp思路是第一次dfs求出x到以x为根的子树的最优方案,第二次与父亲比较求出x到所有点的最优方案,线段树维护区间最大值
看了讨论区里关于24pts的警示后人,感觉按照这个思路处理并不会出现该问题,实际上我没过的点也和那个楼主不一样,故求大佬帮忙看一下
CPP
#include <bits/stdc++.h>
#define ll long long
#define lson(X) ((X) << 1)
#define rson(X) (((X) << 1) | 1)
#define mid ((l + r) >> 1)
#define maxn 200010
using namespace std;
#define writeln(X) write(X), putchar('\n')
template < typename T >
inline void read(T &X)
{
    X = 0; bool f = false; char ch = getchar();
    while (!isdigit(ch)) {f |= ch == '-'; ch = getchar();}
    while (isdigit(ch)) {X = (X * 10) + (ch ^ 48); ch = getchar();}
    X = f ? -X : X;
}
template < typename T >
inline void write(T X)
{
    if (X == 0) {putchar('0'); return;}
    if (X < 0) {putchar('-'); X = -X;}
    static char cnt = 0, num[20];
    while (X) *(num + cnt++) = X % 10, X /= 10;
    while (cnt) putchar(*(num + --cnt) ^ 48);
    return;
}
struct side {int to, nxt, dis;} sidelist[maxn << 1];
int head[maxn], sidecnt;
inline void buildside(const int &u, const int &v, const int &w) {sidelist[++sidecnt] = {v, head[u], w}; head[u] = sidecnt;}
int n, q;
ll c[maxn];
ll d[maxn];
int siz[maxn], heavy[maxn], fa[maxn], dep[maxn];
void dfs1(const int &x)
{
    siz[x] = 1;
    for (int i = head[x]; i; i = sidelist[i].nxt)
    {
        int to = sidelist[i].to, dis = sidelist[i].dis;
        if (to == fa[x]) continue;
        d[to] = d[x] + dis; fa[to] = x; dep[to] = dep[x] + 1;
        dfs1(to);
        siz[x] += siz[to];
        if (siz[to] > siz[heavy[x]]) heavy[x] = to;
    }
}
int lin[maxn], dfn[maxn];
int dfncnt;
void dfs2(const int &x)
{
    dfn[x] = ++dfncnt;
    if (heavy[x]) {lin[heavy[x]] = lin[x]; dfs2(heavy[x]);}
    for (int i = head[x]; i; i = sidelist[i].nxt)
    {
        int to = sidelist[i].to;
        if (to == fa[x] || to == heavy[x]) continue;
        lin[to] = to; dfs2(to);
    }
}
ll dp[maxn];
void dfs3(const int &x)
{
    dp[x] = c[x];
    for (int i = head[x]; i; i = sidelist[i].nxt)
    {
        int to = sidelist[i].to, dis = sidelist[i].dis;
        if (to == fa[x]) continue;
        dfs3(to); dp[x] = max(dp[x], dp[to] - 2ll * dis);
    }
}
void dfs4(const int &x)
{
    for (int i = head[x]; i; i = sidelist[i].nxt)
    {
        int to = sidelist[i].to;
        if (to == fa[x]) continue;
        dfs4(to);
    }
    if (fa[x]) dp[x] = max(dp[x], dp[fa[x]] - 2ll * (d[x] - d[fa[x]]));
}
inline int LCA(int x, int y)
{
    if (dep[lin[x]] > dep[lin[y]]) swap(x, y);
    while (lin[x] != lin[y])
    {
        y = fa[lin[y]];
        if (dep[lin[x]] > dep[lin[y]]) swap(x, y);
    }
    if (dep[x] > dep[y]) swap(x, y);
    return x;
}
int seg[maxn << 2];
void add(const int &x, const int &l, const int &r, const int &loc, const int &val)
{
    if (l == r) {seg[x] = val; return;}
    if (loc <= mid) add(lson(x), l, mid, loc, val);
    else add(rson(x), mid + 1, r, loc, val);
    seg[x] = max(seg[lson(x)], seg[rson(x)]);
}
ll query(const int &x, const int &l, const int &r, const int &lx, const int &rx)
{
    if (l >= lx && r <= rx) {return seg[x];}
    ll res = -0x3f3f3f3f3f3f3f3f;
    if (mid >= lx) res = max(res, query(lson(x), l, mid, lx, rx));
    if (mid + 1 <= rx) res = max(res, query(rson(x), mid + 1, r, lx, rx));
    return res;
}
inline ll treequery(int x, const int &y)
{
    ll res = -0x3f3f3f3f3f3f3f3f;
    while (lin[x] != lin[y])
    {
        res = max(res, query(1, 1, n, dfn[lin[x]], dfn[x]));
        x = fa[lin[x]];
    }
    res = max(res, query(1, 1, n, dfn[y], dfn[x]));
    return res;
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("P11324.in", "r", stdin);
    freopen("P11324.out", "w", stdout);
#endif
    memset(seg, -0x3f, sizeof(seg));
    read(n); read(q);
    for (int i = 1; i <= n; ++i) read(c[i]);
    for (int i = 1; i < n; ++i)
    {
        int u, v, w;
        read(u); read(v); read(w);
        buildside(u, v, w); buildside(v, u, w);
    }
    dep[1] = 1; dfs1(1); lin[1] = 1; dfs2(1); dfs3(1); dfs4(1);
    for (int i = 1; i <= n; ++i) add(1, 1, n, dfn[i], dp[i]);
    for (int i = 1; i <= q; ++i)
    {
        int x, y;
        read(x); read(y);
        int l = LCA(x, y);
        writeln(c[x] + c[y] - (d[x] + d[y] - 2 * d[l]) + max(treequery(x, l), treequery(y, l)));
    }
    return 0;
}
另外捞一下其他两个求助帖 1 2,同样悬赏20rmb

回复

8 条回复,欢迎继续交流。

正在加载回复...