QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#588140#365. Railway Tripmakrav0 1ms3864kbC++208.0kb2024-09-25 03:16:022024-09-25 03:16:02

Judging History

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

  • [2024-09-25 03:16:02]
  • 评测
  • 测评结果:0
  • 用时:1ms
  • 内存:3864kb
  • [2024-09-25 03:16:02]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

#define sz(x) (int)(x).size()
#define pb push_back
#define all(x) (x).begin(), (x).end()

template<typename T>
struct sparsetable {
    int n;
    vector<T> arr;
    vector<vector<T>> sp;
    function<T(T, T)> comp;
    sparsetable() = default;
    sparsetable(int n_, vector<T> arr_, function<T(T, T)> f) {
        n = n_;
        arr = arr_;
        comp = f;
        build();
    }

    void build() {
        int lg = (int) log2(n) + 1;
        sp.assign(lg, vector<T>(n));
        for (int i = 0; i < n; i++) sp[0][i] = arr[i];
        for (int i = 1; i <= lg; i++) {
            for (int j = 0; j + (1 << i) - 1 < n; j++) {
                sp[i][j] = comp(sp[i - 1][j], sp[i - 1][j + (1 << (i - 1))]);
            }
        }
    }

    T get(int l, int r) {
        int lg = 31 - __builtin_clz(r - l + 1);
        return comp(sp[lg][l], sp[lg][r - (1 << lg) + 1]);
    }
};

const int LOGMAX = 17;

void solve() {
    int n, k, q; cin >> n >> k >> q;
    vector<int> a(n);
    for (int i = 0; i < n; i++) cin >> a[i];
    vector<pair<int, int>> b(n);
    for (int i = 0; i < n; i++) b[i] = {a[i], i};
    sparsetable<pair<int, int>> rmax(n, b, [](pair<int, int> p1, pair<int, int> p2){
        if (p1.first != p2.first) return (p1.first < p2.first ? p2 : p1);
        return (p1.second < p2.second ? p2 : p1);
    }), rmin(n, b, [](pair<int, int> p1, pair<int, int> p2){
        if (p1.first != p2.first) return (p1.first < p2.first ? p2 : p1);
        return (p1.second < p2.second ? p1 : p2);
    });

    vector<vector<int>> g(n);
    vector<int> nxt(n, -1), prv(n, -1);
    stack<int> st;
    for (int i = n - 1; i >= 0; i--) {
        while (!st.empty() && a[st.top()] < a[i]) st.pop();
        if (!st.empty()) {
            nxt[i] = st.top();
        }
        st.push(i);
    }
    while (!st.empty()) st.pop();
    for (int i = 0; i < n; i++) {
        while (!st.empty() && a[st.top()] < a[i]) st.pop();
        if (!st.empty()) {
            prv[i] = st.top();
        }
        st.push(i);
    }
    vector<int> rson(n, -1), lson(n, -1);
    auto build = [&](int l, int r, int ps, auto&&self) -> void {
        if (ps < r) {
            int rp = rmin.get(ps + 1, r).second;
            rson[ps] = rp;
            g[ps].pb(rp);
            self(ps + 1, r, rp, self);
        }
        if (ps > l) {
            int lp = rmax.get(l, ps - 1).second;
            lson[ps] = lp;
            g[ps].pb(lp);
            self(l, ps - 1, lp, self);
        }
    };
    build(0, n - 1, 0, build);
    vector<int> h(n), tin(n), tout(n), par(n), jumpv(n, -1), jumpc(n);
    vector<vector<int>> up(LOGMAX, vector<int>(n));
    int tim = 0;
    auto dfs = [&](int v, auto&&self) -> void {
        tin[v] = tim++;
        up[0][v] = par[v];
        for (int i = 1; i < LOGMAX; i++) {
            up[i][v] = up[i - 1][up[i - 1][v]];
        }
        for (auto &u : g[v]) {
            par[u] = v;
            h[u] = h[v] + 1;
            self(u, self);
        }
        tout[v] = tim++;
    };
    dfs(0, dfs);
    
    auto is_par = [&](int u, int v) {
        return tin[u] <= tin[v] && tout[v] <= tout[u];
    };
    auto lca = [&](int u, int v) {
        if (is_par(u, v)) return u;
        if (is_par(v, u)) return v;
        for (int i = LOGMAX - 1; i >= 0; i--) {
            if (!is_par(up[i][u], v)) u = up[i][u];
        }
        return up[0][u];
    };

    for (int i = 0; i < n; i++) {
        if (rson[par[i]] == i && lson[par[par[i]]] == par[i]) {
            vector<int> pathr = {i};
            while (rson[pathr.back()] != -1) pathr.pb(rson[pathr.back()]);

            vector<int> used(sz(pathr), 0);
            for (int j = 0; j < sz(pathr); j++) {
                jumpv[pathr[j]] = par[par[i]];
                if (nxt[pathr[j]] == par[par[i]]) used[j] = 1;
            }
            vector<int> lind(sz(pathr), -1), rind(sz(pathr), -1);
            for (int j = 0; j < sz(pathr); j++) {
                if (j > 0) lind[j] = lind[j - 1];
                if (used[j]) lind[j] = j;
            }
            for (int j = sz(pathr) - 1; j >= 0; j--) {
                if (j < sz(pathr) - 1) rind[j] = rind[j + 1];
                if (used[j]) rind[j] = j;
            }
            for (int j = 0; j < sz(pathr); j++) {
                jumpc[pathr[j]] = j + 2;
                if (lind[j] != -1) jumpc[pathr[j]] = min(jumpc[pathr[j]], j - lind[j] + 1);
                if (rind[j] != -1) jumpc[pathr[j]] = min(jumpc[pathr[j]], rind[j] - j + 1);
            }
        }
    }

    for (int i = 0; i < n; i++) {
        if (lson[par[i]] == i && rson[par[par[i]]] == par[i]) {
            vector<int> pathr = {i};
            while (lson[pathr.back()] != -1) pathr.pb(lson[pathr.back()]);

            vector<int> used(sz(pathr), 0);
            for (int j = 0; j < sz(pathr); j++) {
                jumpv[pathr[j]] = par[par[i]];
                if (prv[pathr[j]] == par[par[i]]) used[j] = 1;
            }
            vector<int> lind(sz(pathr), -1), rind(sz(pathr), -1);
            for (int j = 0; j < sz(pathr); j++) {
                if (j > 0) lind[j] = lind[j - 1];
                if (used[j]) lind[j] = j;
            }
            for (int j = sz(pathr) - 1; j >= 0; j--) {
                if (j < sz(pathr) - 1) rind[j] = rind[j + 1];
                if (used[j]) rind[j] = j;
            }
            for (int j = 0; j < sz(pathr); j++) {
                jumpc[pathr[j]] = j + 2;
                if (lind[j] != -1) jumpc[pathr[j]] = min(jumpc[pathr[j]], j - lind[j] + 1);
                if (rind[j] != -1) jumpc[pathr[j]] = min(jumpc[pathr[j]], rind[j] - j + 1);
            }
        }
    }

    auto getd1 = [&](int v1, int v2) {
        //if (jumpv[v1] != jumpv[v2]) return (int) 1e9;
        //assert(jumpv[v1] == jumpv[v2]);
        int st = abs(h[v1] - h[v2]);
        if (jumpv[v1] != -1 && jumpv[v1] == jumpv[v2]) {
            st = min(st, jumpc[v1] + jumpc[v2]);
        }
        return st;
    };

    vector<int> ord(n);
    iota(all(ord), 0);
    sort(all(ord), [&](int i, int j){
        return h[i] < h[j];
    });
    vector<vector<int>> up_jumps(LOGMAX, vector<int>(n)), sm_jumps(LOGMAX, vector<int>(n));
    for (int v : ord) {
        up_jumps[0][v] = jumpv[v];
        sm_jumps[0][v] = jumpc[v];
        for (int i = 1; i < LOGMAX; i++) {
            up_jumps[i][v] = (up_jumps[i - 1][v] == -1 ? -1 : up_jumps[i - 1][up_jumps[i - 1][v]]);
            sm_jumps[i][v] = sm_jumps[i - 1][v] + (up_jumps[i - 1][v] == -1 ? 0 : sm_jumps[i - 1][up_jumps[i - 1][v]]);
        }
    }
    
    // for (int i = 0; i < n; i++) cout << jumpv[i] << ' ';
    // cout << '\n';
    // for (int i = 0; i < n; i++) cout << jumpc[i] << ' ';
    // cout << '\n';
    while (q--) {
        int u, v; cin >> u >> v;
        u--; v--;
        if (h[u] > h[v]) swap(u, v);
        int lc = lca(u, v);

        int S = 0;
        for (int i = LOGMAX - 1; i >= 0; i--) {
            if (up_jumps[i][u] != -1 && is_par(lc, up_jumps[i][u])) {
                S += sm_jumps[i][u];
                u = up_jumps[i][u];
            }
            if (up_jumps[i][v] != -1 && is_par(lc, up_jumps[i][v])) {
                S += sm_jumps[i][v];
                v = up_jumps[i][v];
            }
        }
        if (v == lc || u == lc) {
            cout << S + getd1(v, u) - 1 << '\n';
            continue;
        }
        int ans1 = S + min(h[u] - h[lc] + getd1(v, lc), h[v] - h[lc] + getd1(u, lc));
        if (jumpv[v] != -1) ans1 = min(ans1, S + jumpc[v] + getd1(u, jumpv[v]));
        if (jumpv[u] != -1) ans1 = min(ans1, S + jumpc[u] + getd1(jumpv[u], v));
        cout<< ans1 - 1 << '\n';
    }
}

signed main() {
    int tt = 1;
    #ifdef LOCAL 
        freopen("in.txt", "r", stdin);
        freopen("out.txt", "w", stdout);
        cin >> tt;
    #else 
        ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    #endif

    while (tt--) {
        solve();
    }
    return 0;
}

詳細信息

Subtask #1:

score: 0
Wrong Answer

Test #1:

score: 0
Wrong Answer
time: 1ms
memory: 3864kb

input:

100 100 50
100
86
39
28
49
22
79
14
83
100
15
26
37
51
53
18
74
15
96
72
47
80
10
46
62
88
20
36
46
29
40
28
37
88
91
41
24
63
14
92
24
31
99
61
62
96
94
51
51
21
72
97
59
96
97
94
66
88
32
96
58
26
53
1
100
31
85
30
42
69
40
62
54
94
49
62
13
20
82
74
20
44
54
69
65
34
78
64
48
69
19
35
8
92
100
87...

output:

3
1
3
5
3
3
5
0
2
5
2
6
1
3
1
3
5
5
3
5
4
7
3
6
3
4
4
4
8
0
2
3
2
4
5
5
6
5
5
6
4
3
2
8
5
2
6
4
2
2

result:

wrong answer 7th lines differ - expected: '3', found: '5'

Subtask #2:

score: 0
Skipped

Dependency #1:

0%

Subtask #3:

score: 0
Skipped

Dependency #1:

0%

Subtask #4:

score: 0
Skipped

Dependency #1:

0%