QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#779463#365. Railway Tripmakrav0 1ms3968kbC++207.2kb2024-11-24 19:15:212024-11-24 19:15:22

Judging History

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

  • [2024-11-24 19:15:22]
  • 评测
  • 测评结果:0
  • 用时:1ms
  • 内存:3968kb
  • [2024-11-24 19:15:21]
  • 提交

answer

#include <bits/stdc++.h>
#include <cassert>

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;
    //cout << n << ' ' << k << ' ' << q  << '\n';
    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), g2(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();
            g2[i].pb(nxt[i]);
            g2[nxt[i]].pb(i);
        }
        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();
            g2[i].pb(prv[i]);
            g2[prv[i]].pb(i);
        }
        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);
            g[rp].pb(ps);
            self(ps + 1, r, rp, self);
        }
        if (ps > l) {
            int lp = rmax.get(l, ps - 1).second;
            lson[ps] = lp;
            g[ps].pb(lp);
            g[lp].pb(ps);
            self(l, ps - 1, lp, self);
        }
    };
    build(0, n - 1, 0, build);
    
    vector<vector<pair<int, int>>> qrs(n);
    vector<pair<int, int>> Q(q);
    for (int i = 0; i < q; i++) {
        int u, v; cin >> u >> v;
        u--; v--;
        Q[i] = {u, v};
        qrs[u].pb({v, i});
        qrs[v].pb({u, i});
    }
    vector<int> ans(q, n + 1);
    //cout << ans.size() << '\n';
    vector<int> tin(n), tout(n), h(n);
    int timer = 0;
    auto dfs = [&](int v, int p, auto&&self) -> void {
        tin[v] = timer++;
        for (int u : g[v]) {
            if (u != p) {
                h[u] = h[v] + 1;
                self(u, v, self);
            }
        }
        tout[v] = timer++;
    };
    dfs(0, 0, dfs);
    auto is_par = [&](int v1, int v2) {
        return tin[v1] <= tin[v2] && tout[v2] <= tout[v1];
    };
    
    vector<int> used_cent(n), need_find(n), siz(n), used(n);
    vector<vector<int>> cent_cmp(n);
    need_find[0] = 1;
    int cur = 1, step = 0;
    vector<int> curcmp;
    auto dfs_siz = [&](int v, auto&&self) -> void {
        siz[v] = 1; used[v] = step; curcmp.pb(v);
        for (int u : g[v]) {
            if (used[u] != step && !used_cent[u]) {
                self(u, self);
                siz[v] += siz[u];
            }
        }
    };
    auto find_cent = [&](int v, int init_size, auto&&self) -> int {
        used[v] = step;
        for (int u : g[v]) {
            if (used[u] != step && !used_cent[u] && siz[u] > init_size / 2) return self(u, init_size, self);
        }
        return v;
    };
    while (true) {
        bool allgood = true;
        for (int i = 0; i < n; i++) {
            if (need_find[i] == cur) {
                curcmp.clear();
                allgood = false;
                step++; dfs_siz(i, dfs_siz); step++;
                int vt = find_cent(i, siz[i], find_cent);
                //cout << i << ' ' << cur << ' ' << vt << '\n';
                used_cent[vt] = 1;
                cent_cmp[vt] = curcmp;
                for (int u : g[vt]) {
                    if (!used_cent[u]) need_find[u] = cur + 1;
                }
            }
        }
        if (allgood) break;
        cur++;
    }
    vector<int> pos(n);
    for (int i = 0; i < n; i++) {
        // cout << i << endl;
        // for (int u : cent_cmp[i]) cout << u << ' ';
        // cout << endl;
        step++;
        for (int u : cent_cmp[i]) used[u] = step;
        vector<int> curq;
        for (int u : cent_cmp[i]) {
            for (auto [v, num] : qrs[u]) {
                if (v > u && used[v] == step) curq.pb(num);
            }
        }
        unordered_set<int> roots;
        roots.insert(i);
        for (int u : cent_cmp[i]) {
            if (u != i && nxt[u] != -1 &&  is_par(i, u) && is_par(nxt[u], i) && used[nxt[i]] == step) {
                roots.insert(nxt[u]);
            }
            if (u != i && prv[u] != -1 && is_par(i, u) && is_par(prv[u], i) && used[prv[i]] == step) {
                roots.insert(prv[u]);
            }
        }
        for (int j = 0; j < cent_cmp[i].size(); j++) pos[cent_cmp[i][j]] = j;
        vector<vector<int>> newg(sz(cent_cmp[i]));
        for (int j = 0; j < cent_cmp[i].size(); j++) {
            for (int u : g2[cent_cmp[i][j]]) {
                if (used[u] == step) newg[j].pb(pos[u]);
            }
        }
        for (int rt : roots) {
            vector<int> dist(sz(cent_cmp[i]), -1);
            //assert(rt == i || used[rt] == step);
            dist[pos[rt]] = 0;
            queue<int> q;
            q.push(pos[rt]);
            while (!q.empty()) {
                int V = q.front();
                q.pop();
                for (int u : newg[V]) {
                    if (dist[u] == -1) {
                        dist[u] = dist[V] + 1;
                        q.push(u);
                    }
                }
            }
            for (int qnum : curq) {
                ans[qnum] = min(ans[qnum], dist[pos[Q[qnum].first]] + dist[pos[Q[qnum].second]]);
            }
        }
    }
    //cout << sz(ans) << '\n';
    for (int el : ans) cout << el - 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;
}

Details

Tip: Click on the bar to expand more detailed information

Subtask #1:

score: 0
Runtime Error

Test #1:

score: 5
Accepted
time: 0ms
memory: 3660kb

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
3
0
2
5
2
6
1
3
1
3
5
5
3
5
4
7
3
6
3
4
4
4
7
0
2
3
2
4
5
5
6
5
5
6
4
3
2
4
5
2
5
4
2
2

result:

ok 50 lines

Test #2:

score: 5
Accepted
time: 1ms
memory: 3712kb

input:

100 100 50
100
85
82
7
50
49
51
45
30
3
29
99
71
93
5
68
70
52
12
44
1
35
99
80
76
34
23
28
62
91
80
77
59
57
30
15
23
13
16
21
58
23
38
49
44
73
7
47
24
53
97
83
14
71
16
75
61
24
17
96
51
41
74
53
25
2
42
36
73
57
53
45
10
12
11
79
68
2
78
44
47
67
21
99
25
68
60
71
23
92
9
2
97
37
43
64
32
28
7
1...

output:

2
0
5
4
2
4
2
4
3
5
4
3
3
6
4
4
3
3
3
4
2
3
3
3
4
5
5
2
3
3
5
4
3
4
2
2
3
5
3
6
2
5
4
2
2
4
4
3
4
7

result:

ok 50 lines

Test #3:

score: 5
Accepted
time: 1ms
memory: 3832kb

input:

100 100 50
100
56
83
81
2
73
24
77
19
11
79
100
36
32
62
4
41
50
51
62
68
6
11
36
28
21
61
82
72
86
35
93
94
87
50
14
77
83
14
49
95
32
5
20
59
55
77
31
52
70
23
81
4
10
34
100
4
67
60
1
23
26
65
1
30
96
43
49
70
81
18
82
97
80
62
28
93
38
91
39
67
6
17
78
60
60
55
97
45
58
44
80
24
91
14
5
35
93
25...

output:

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

result:

ok 50 lines

Test #4:

score: 5
Accepted
time: 1ms
memory: 3968kb

input:

100 100 50
100
50
72
67
84
3
28
84
40
70
52
28
37
16
66
92
47
27
30
49
33
7
69
22
33
85
1
98
4
97
89
27
99
21
33
76
89
26
74
10
80
23
70
10
63
1
78
38
28
30
95
11
17
99
10
52
5
30
38
95
4
71
50
2
40
28
17
21
10
13
23
98
92
84
8
3
37
38
71
78
57
87
22
79
59
26
13
50
33
87
9
6
78
85
19
68
79
9
62
100
...

output:

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

result:

ok 50 lines

Test #5:

score: 5
Accepted
time: 1ms
memory: 3716kb

input:

100 100 50
100
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
100
91 65
31 33
13 98
45 91
54 50
94 66
78 5
28 13
100 4
15 63
55 2
72 49
97 18
57 59
40 ...

output:

25
1
14
45
3
27
26
14
3
47
46
22
20
1
6
1
22
27
15
39
25
36
35
24
14
12
35
32
48
5
9
2
26
4
27
17
36
35
10
15
38
7
16
2
48
3
31
32
48
6

result:

ok 50 lines

Test #6:

score: 0
Runtime Error

input:

100 100 50
100
99
99
99
97
97
97
95
95
95
93
93
93
91
91
91
89
89
89
87
87
87
85
85
85
83
83
83
81
81
81
79
79
79
77
77
77
75
75
75
73
73
73
71
71
71
69
69
69
67
67
67
68
68
70
70
70
72
72
72
74
74
74
76
76
76
78
78
78
80
80
80
82
82
82
84
84
84
86
86
86
88
88
88
90
90
90
92
92
92
94
94
94
96
96
96
...

output:


result:


Subtask #2:

score: 0
Skipped

Dependency #1:

0%

Subtask #3:

score: 0
Skipped

Dependency #1:

0%

Subtask #4:

score: 0
Skipped

Dependency #1:

0%