求调悬关
查看原帖
求调悬关
531746
Composite_Function楼主2024/5/28 23:38
#include <bits/stdc++.h>
using namespace std;

struct FastIO
{
    inline FastIO& operator >> (int& x) {
        x = 0; char f = 0, ch = getchar();
        while(ch > '9' || ch < '0') f |= (ch == '-'), ch = getchar();
        while(ch <= '9' && ch >= '0') x = x * 10 + ch - 48, ch = getchar();
        return x = (f ? -x : x), *this;
    }
    inline FastIO& operator >> (long long& x) {
        x = 0; char f = 0, ch = getchar();
        while(ch > '9' || ch < '0') f |= (ch == '-'), ch = getchar();
        while(ch <= '9' && ch >= '0') x = x * 10 + ch - 48, ch = getchar();
        return x = (f ? -x : x), *this;
    }
    inline FastIO& operator >> (__int128& x) {
        x = 0; char f = 0, ch = getchar();
        while(ch > '9' || ch < '0') f |= (ch == '-'), ch = getchar();
        while(ch <= '9' && ch >= '0') x = x * 10 + ch - 48, ch = getchar();
        return x = (f ? -x : x), *this;
    }
    inline FastIO& operator >> (double& x) {
        x = 0; char f = 0, ch = getchar();
        double d = 0.1;
        while(ch > '9' || ch < '0') f |= (ch == '-'), ch = getchar();
        while(ch <= '9' && ch >= '0') x = x * 10 + ch - 48, ch = getchar();
        if(ch == '.')
        {
            ch = getchar();
            while(ch <= '9' && ch >= '0') x += d * (ch ^ 48), d *= 0.1, ch = getchar();
        }
        return x = (f ? -x : x), *this;
    }
}rin;

const int N = 1e5 + 10;

int id, n, t, s[N];

// 链式前向星
int to[N << 1], head[N << 1], nxt[N << 1], w[N << 1], w_[N << 1];
int totE;
inline void init() {
    totE = 0;
    memset(head, -1, sizeof(head));
}
inline void addDirEdge(const int& u, const int& v, const int& _w, const int& _w_) {
    nxt[++totE] = head[u];
    head[u] = totE;
    to[totE] = v;
    w[totE] = _w;
    w_[totE] = _w_;
}
inline void addEdge(const int& u, const int& v, const int& _w, const int& _w_) {
    addDirEdge(u, v, _w, _w_);
    addDirEdge(v, u, _w, _w_);
}

// 计算子树大小 计算初始答案
__int128 orgAns;
long long sz[N], sum;
inline void dfs1(int u = 1, int fa = -1) {
    sz[u] = s[u];
    for (int i = head[u]; i != -1; i = nxt[i]) {
        if (to[i] != fa) {
            dfs1(to[i], u);
            sz[u] += sz[to[i]];
            orgAns += (__int128)sz[to[i]] * (sum - sz[to[i]]) * w[i];
        }
    }
}

// 凸包
struct Point {
    __int128 x, y;
};
inline bool operator <(const Point& pA, const Point& pB)  {
    return pA.x == pB.x? pA.y < pB.y : pA.x < pB.x;
}
inline bool operator ==(const Point& pA, const Point& pB) {
    return pA.x == pB.x;
}
inline __float128 slope(const Point& pA, const Point& pB) {
    return (__float128)(pA.y - pB.y) / (pA.x - pB.x);
}
int totP;
int l, r, q[N];
Point p[N];

// DP
__int128 dp[N], Mx;
inline void dfs2(int u = 1, int fa = -1, __int128 e = 0) {
    dp[u] = e;
    for (int i = head[u]; i != -1; i = nxt[i]) {
        if (to[i] != fa) {
            dfs2(to[i], u, (__int128)sz[to[i]] * (sum - sz[to[i]]) * (w[i] - w_[i] - t));
            if (fa != -1) dp[u] = max(dp[u], e + dp[to[i]] + (__int128)sz[to[i]] * (sum - sz[u]) * t);
            Mx = max(Mx, dp[u]);
        } 
    }

    totP = 0;
    for (int i = head[u]; i != -1; i = nxt[i]) {
        if (to[i] != fa) {
            p[++totP] = (Point){sz[to[i]], dp[to[i]]};
        }
    }

    sort(p + 1, p + totP + 1);
    
    for (int i = 1; i + 1 <= totP; ++i) {
        if (p[i] == p[i + 1]) {
            Mx = max(Mx, p[i].y + p[i + 1].y + p[i].x * p[i + 1].x * t);
        }
    }

    int curP = unique(p + 1, p + totP + 1) - p - 1;

    q[l = r = 1] = 1;
    for (int i = 2; i <= curP; ++i) {
        while (l < r && slope(p[q[l]], p[q[l + 1]]) >= -t * p[i].x) ++l;
        Mx = max(Mx, p[i].y + p[q[l]].y + p[i].x * p[q[l]].x * t);
        while (l < r && slope(p[q[r - 1]], p[q[r]]) <= slope(p[q[r]], p[i])) --r;
        q[++r] = i;
    }
}

// 输出
inline void output(__int128 ans) {
    string str;
    if (!ans) {
        str = "0";
    } else {
        str = "";
        while (ans) {
            str = ((char)('0' + ans % 10)) + str;
            ans /= 10;
        }
    }
    cout << str << endl;
}

// 解决问题
void solve() {
    dfs1();
    dfs2();
    orgAns -= Mx;
    output(orgAns);
}

signed main() {
    rin >> id >> n >> t;
    for (int i = 1; i <= n; ++i) {
        rin >> s[i];
        sum += s[i];
    }
    init();
    for (int i = 1, u, v, w, w_; i < n; ++i) {
        rin >> u >> v >> w >> w_;
        addEdge(u, v, w, w_);
    }
    solve();
    return 0;
}

WA 一个点,求调。

2024/5/28 23:38
加载中...