QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#610221#5363. ZYB 的游览计划forgotmyhandle0 0ms0kbC++144.3kb2024-10-04 15:18:282024-10-04 15:18:28

Judging History

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

  • [2024-10-04 15:18:28]
  • 评测
  • 测评结果:0
  • 用时:0ms
  • 内存:0kb
  • [2024-10-04 15:18:28]
  • 提交

answer

#include <iostream>
#include <algorithm>
#include <string.h>
#include <cassert>
#include <random>
#include <set>
#define int long long
using namespace std;
random_device rd;
mt19937 mtrand(rd());
int n, m;
int a[200005];
int head[200005], nxt[400005], to[400005], ecnt;
void add(int u, int v) { to[++ecnt] = v, nxt[ecnt] = head[u], head[u] = ecnt; }
int top[200005], dep[200005], son[200005], sz[200005], f[200005];
int dfn[200005], _dfn[200005], ncnt;
void dfs1(int x, int fa, int d) {
    dep[x] = d;
    f[x] = fa;
    sz[x] = 1;
    for (int i = head[x]; i; i = nxt[i]) {
        int v = to[i];
        if (v != fa) {
            dfs1(v, x, d + 1);
            sz[x] += sz[v];
            if (sz[v] > sz[son[x]]) 
                son[x] = v;
        }
    }
}
void dfs2(int x, int t) {
    top[x] = t;
    _dfn[dfn[x] = ++ncnt] = x;
    if (!son[x]) 
        return;
    dfs2(son[x], t);
    for (int i = head[x]; i; i = nxt[i]) {
        int v = to[i];
        if (v != f[x] && v != son[x]) 
            dfs2(v, v);
    }
}
int LCA(int x, int y) {
    while (top[x] ^ top[y]) (dep[top[x]] < dep[top[y]]) ? (y = f[top[y]]) : (x = f[top[x]]);
    return (dep[x] < dep[y] ? x : y);
}
int dist(int x, int y) { return dep[x] + dep[y] - 2 * dep[LCA(x, y)]; }
set<int> st;
int cur = 0;
void Add(int x) {
    // cout << "Add " << x << "\n";
    if (x == 1) 
        return;
    assert(st.size());
    int a, b;
    int d = dfn[x];
    set<int>::iterator it = st.upper_bound(d);
    b = (it != st.end() ? _dfn[*it] : _dfn[*st.begin()]);
    assert(it != st.begin());
    --it;
    a = _dfn[*it];
    cur -= dist(a, b);
    cur += dist(a, x);
    cur += dist(b, x);
    st.insert(dfn[x]);
}
void Erase(int x) {
    // cout << "Erase " << x << "\n";
    if (x == 1) 
        return;
    assert(st.size());
    int a, b;
    int d = dfn[x];
    assert(st.count(d));
    st.erase(st.find(d));
    set<int>::iterator it = st.upper_bound(d);
    b = (it != st.end() ? _dfn[*it] : _dfn[*st.begin()]);
    assert(it != st.begin());
    --it;
    a = _dfn[*it];
    cur += dist(a, b);
    cur -= dist(a, x);
    cur -= dist(b, x);
}
int dp[450][200005];
int _l = 1, _r;
void Move(int tl, int tr) {
    // cout << tl << " " << tr << "\n";
    while (_r < tr) Add(a[++_r]);
    while (_l > tl) Add(a[--_l]);
    while (_r > tr) Erase(a[_r--]);
    while (_l < tl) Erase(a[_l++]);
}
void Solve(int l, int r, int L, int R, int k) {
    if (l > r) 
        return;
    int mid = (l + r) >> 1;
    int p = L;
    for (int i = L; i <= mid; i++) {
        Move(i, mid);
        if (dp[k - 1][i - 1] + cur > dp[k][mid]) {
            dp[k][mid] = dp[k - 1][i - 1] + cur;
            p = i;
        }
    }
    // cout << k << " " << mid << " " << p << " " << dp[k][mid] << "\n";
    Solve(l, mid - 1, L, p, k);
    Solve(mid + 1, r, p, R, k);
}
signed main() {
    // while (1) {
    //     ncnt = ecnt = 0;
    //     memset(son, 0, sizeof son);
    //     memset(head, 0, sizeof head);
    //     n = 10, m = mtrand() % 5 + 1;
    //     st.clear();
    //     cur = _l = 1, _r = 0;
    //     cout << n << " " << m << "\n";
    //     for (int i = 1; i <= n; i++) a[i] = i;
    //     shuffle(a + 1, a + n + 1, mtrand);
    //     for (int i = 1; i <= n; i++) cout << a[i] << " ";
    //     cout << "\n";
    //     for (int i = 1; i < n; i++) {
    //         int u, v;
    //         u = i + 1, v = mtrand() % i + 1;
    //         cout << u << " " << v << "\n";
    //         add(u, v);
    //         add(v, u);
    //     }
        cin >> n >> m;
        for (int i = 1; i <= n; i++) cin >> a[i];
        for (int i = 1; i < n; i++) {
            int u, v;
            cin >> u >> v;
            add(u, v);
            add(v, u);
        }
        dfs1(1, 0, 1);
        dfs2(1, 1);
        st.insert(1);
        memset(dp, 0, sizeof dp);
        for (int i = 1; i <= n; i++) {
            Add(a[i]);
            dp[1][i] = cur;
            // cout << i << " " << dp[1][i] << "\n";
        }
        for (int i = 1; i <= n; i++) Erase(a[i]);
        for (int i = 2; i <= m; i++) Solve(i, n, i, n, i);
        cout << dp[m][n] << "\n";
    // }
    return 0;
}
/*
10 2
8 9 3 2 4 1 5 10 7 6
2 1
3 1
4 3
5 1
6 2
7 3
8 7
9 8
10 7
*/

Details

Tip: Click on the bar to expand more detailed information

Subtask #1:

score: 0
Memory Limit Exceeded

Test #1:

score: 0
Memory Limit Exceeded

input:

5 2
2 4 3 5 1
1 2
2 3
3 4
4 5

output:

14

result:


Subtask #2:

score: 0
Memory Limit Exceeded

Test #10:

score: 0
Memory Limit Exceeded

input:

760 217
632 417 493 400 316 482 542 614 36 134 604 291 745 484 451 746 518 378 487 650 633 223 601 259 33 257 309 683 705 627 513 670 130 395 512 115 466 376 575 356 180 716 539 403 431 563 568 468 596 239 296 379 537 224 526 215 725 234 663 603 401 21 75 660 506 393 105 88 462 620 449 338 276 200 4...

output:

35938

result:


Subtask #3:

score: 0
Skipped

Dependency #2:

0%

Subtask #4:

score: 0
Time Limit Exceeded

Test #29:

score: 0
Time Limit Exceeded

input:

14878 6
1663 4532 2022 11114 1768 7744 12403 7698 14863 1406 13199 9405 3528 9898 1205 3076 11342 7459 9401 10025 14498 7178 11457 1802 9923 1648 13136 10720 3002 7332 13780 2094 1716 13215 8118 318 11186 14833 7941 8174 8999 6189 7504 13738 4933 3367 12973 1889 9835 4080 3546 1993 1861 11613 2504 1...

output:


result:


Subtask #5:

score: 0
Skipped

Dependency #1:

0%