QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#583945#5418. Color the TreeLongvuRE 0ms25192kbC++143.9kb2024-09-23 00:15:212024-09-23 00:15:21

Judging History

你现在查看的是最新测评结果

  • [2024-09-23 00:15:21]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:25192kb
  • [2024-09-23 00:15:21]
  • 提交

answer

/**
 *    author:  longvu
 *    created: 09/22/24 22:35:37
**/
#include<bits/stdc++.h>

using namespace std;

#define int long long
#define sz(x) ((int)x.size())
#define all(x) (x).begin(), (x).end()
const int INF = 1e18;
const int nax = (int)(201001);
const int mod = 1e9 + 7;

template<class X, class Y>
bool maximize(X& x, const Y y) {
    if (y > x) {x = y; return true;}
    return false;
}
template<class X, class Y>
bool minimize(X& x, const Y y) {
    if (y < x) {x = y; return true;}
    return false;
}

#define Fi first
#define Se second

const int LOG = 18;

pair<int, int> rmq[nax][LOG + 1];
int euler[nax], h[nax], Log2[nax], fir[nax];
vector<int> adj[nax];
int m = 0;
void dfs(int u, int pa) {
    euler[++m] = u;
    fir[u] = m;
    rmq[m][0] = {h[euler[m]], euler[m]};
    for (auto v : adj[u]) {
        if (v == pa) {
            continue;
        }
        h[v] = 1 + h[u];
        dfs(v, u);
        euler[++m] = u;
        rmq[m][0] = {h[euler[m]], euler[m]};
    }
}

void precal() {
    m = 0;
    dfs(1, -1);
    for (int k = 1; k <= LOG; ++k) {
        for (int i = 1; i + (1 << k) - 1 <= m; ++i) {
            rmq[i][k] = min(rmq[i][k - 1], rmq[i + (1 << (k - 1))][k - 1]);
        }
    }
}

int find_lca(int u, int v) {
    int l = min(fir[u], fir[v]), r = max(fir[u], fir[v])
                                     , k = Log2[r - l + 1];
    return min(rmq[l][k], rmq[r - (1 << k) + 1][k]).Se;
}

int a[nax], dp[nax], rmqp[nax][LOG + 1];
vector<int> memo[nax];
int32_t main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    for (int i = 2; i < nax; ++i) {
        Log2[i] = 1 + Log2[i >> 1];
    }
    int tt;
    cin >> tt;
    while (tt--) {
        int n;
        cin >> n;
        for (int i = 0; i < n; ++i) {
            cin >> a[i];
            rmqp[i][0] = a[i];
        }
        for (int k = 1; k <= LOG; ++k) {
            for (int i = 0; i + (1 << k) - 1 < n; ++i) {
                rmqp[i][k] = min(rmqp[i][k - 1], rmqp[i + (1 << (k - 1))][k - 1]);
            }
        }
        auto get = [&](int l, int r) {
            int k = Log2[r - l + 1];
            return min(rmqp[l][k], rmqp[r - (1 << k) + 1][k]);
        };
        for (int i = 0; i <= n; ++i) {
            adj[i].clear();
            memo[i] = { -1};
        }
        for (int i = 1; i < n; ++i) {
            int u, v;
            cin >> u >> v;
            adj[u].push_back(v);
            adj[v].push_back(u);
        }
        precal();
        for (int i = 1; i <= n; ++i) {
            memo[h[i]].push_back(i);
        }
        int ans = 0;
        for (int hi = 0; hi < n; ++hi) {
            sort(1 + all(memo[hi]), [&](int u, int v) {
                return fir[u] < fir[v];
            });
            for (int i = 0; i < sz(memo[hi]); ++i) {
                dp[i] = INF;
            }
            dp[0] = 0;
            for (int i = 1; i < sz(memo[hi]); ++i) {
                if (sz(memo[hi]) == 1) {
                    continue;
                }
                int l = 1, r = i;
                auto cal = [&](int z) {
                    return get(hi - h[find_lca(memo[hi][z], memo[hi][i])], hi) + dp[z - 1];
                };
                while (r - l >= 1) {
                    int mid1 = (2 * l + r) / 3, mid2 = (l + 2 * r) / 3;
                    if (cal(mid1) >= cal(mid2)) {
                        l = mid1 + 1;
                    } else {
                        r = mid2 - 1;
                    }
                }
                l--;
                for (int j = max(1LL, l - 21); j <= min(l + 21, i); ++j) {
                    minimize(dp[i], cal(j));
                }
                assert(dp[i - 1] <= dp[i]);
            }
            // cout << hi << " " << dp[sz(memo[hi]) - 1] << '\n';
            ans += dp[sz(memo[hi]) - 1];
        }
        cout << ans << '\n';
    }
    return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 0ms
memory: 25192kb

input:

3
4
10 15 40 1
1 2
2 3
2 4
5
10 5 1 100 1000
1 2
2 3
2 4
4 5
4
1000 200 10 8
1 2
2 3
3 4

output:

35
17
1218

result:

ok 3 number(s): "35 17 1218"

Test #2:

score: -100
Runtime Error

input:

3000
54
43 44 11 49 17 14 7 30 35 12 34 14 15 8 29 47 30 31 39 17 26 23 26 45 34 50 49 13 35 18 29 15 13 44 47 5 22 20 19 46 30 22 26 13 47 46 43 27 48 48 13 14 30 44
1 2
1 3
2 4
3 5
4 6
2 7
4 8
1 9
3 10
1 11
8 12
2 13
9 14
1 15
1 16
15 17
15 18
7 19
1 20
19 21
13 22
10 23
17 24
9 25
9 26
24 27
8 28...

output:


result: