QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#537268#2559. Endless Roadsuspicious-impostorWA 0ms27260kbC++208.2kb2024-08-30 05:08:212024-08-30 05:08:21

Judging History

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

  • [2024-08-30 05:08:21]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:27260kb
  • [2024-08-30 05:08:21]
  • 提交

answer



#pragma GCC optimize ("O3")
#pragma GCC optimize ("unroll-loops")
#include <vector>
#pragma GCC target ("avx2")

#include<bits/stdc++.h>
#include<math.h>
using namespace std;

typedef long long int ll;
typedef long double ld;
typedef pair<ll, ll> pl;
typedef vector<ll> vl;
#define FD(i, r, l) for(ll i = r; i > (l); --i)

#define K first
#define V second
#define G(x) ll x; cin >> x;
#define GD(x) ld x; cin >> x;
#define GS(s) string s; cin >> s;
#define EX(x) { cout << x << '\n'; exit(0); }
#define A(a) (a).begin(), (a).end()
#define F(i, l, r) for (ll i = l; i < (r); ++i)

template<typename A, typename B>
A& chmax(A &a, B b) { return a < b ? (a=b): a; }

template<typename A, typename B>
A& chmin(A &a, B b) { return a > b ? (a=b): a; }

const ll N = 5e5 + 10;
const ll NN = N;
const ll L = 20;
ll len[N]; 
ll pos[N]; // position of index in ord
vector<pair<pl, ll>> ord; // intervals sorted according to greedy order

namespace seg_active { // just sum of active things in interval
    typedef ll T;
    T id=0;
    T f(T a, T b) {return a+b;}

    T t[2 * NN];
    ll n=NN;  // array size

    void modify(ll p, T value) {  // set value at position p
      for (p+=n, t[p] = value; p /= 2;) t[p] = f(t[2*p], t[2*p+1]);
    }

    T query(ll l, ll r) { // fold f on interval [l, r)
      T resl=id, resr=id;
      for (l += n, r += n; l < r; l /= 2, r /= 2) {
        if (l&1) resl = f(resl, t[l++]);
        if (r&1) resr = f(t[--r], resr);
      }
      return f(resl, resr);
    }
}


namespace lztree { // segtree of active intervals, maintains candidate set
    typedef pl T;
    typedef ll U;

    T idT = {1e17, -1}, t[2 * N];
    U idU = 0, d[N];
    ll x = (fill_n(d, N, idU), 0);

    // combining segtree nodes a and b
    T f(T a, T b) { 
        if (a == idT) return b;
        if (b == idT) return a;
        if (a.K != b.K) return min(a, b);
        return {a.K, ord[a.V].V < ord[b.V].V ? a.V : b.V }; // note that wthe actual index is ord_idx (the segtree index), but we sort by origianl indcies
    }
    // applying updates a and b (in that order)
    U g(U b, U a) { return a + b; }
    // applying update b to segtree node a
    T h(U b, T a) { return {a.K + b, a.V}; }

    void calc(ll p) { t[p] = h(d[p], f(t[p * 2], t[p * 2 + 1])); }

    void apply(ll p, U v) {
        t[p] = h(v, t[p]);
        if(p < N) d[p] = g(v, d[p]);
    }

    void push(ll p) {
        p += N;
        FD(s, L, 0) {
            ll i = p >> s;
            if(d[i] != idU) {
                apply(i * 2, d[i]);
                apply(i * 2 + 1, d[i]);
                d[i] = idU;
            }
        }
    }

    void modify(ll p, T v) {
        push(p);
        t[p += N] = v;
        while(p > 1) calc(p /= 2);
    }

    void modify(ll l, ll r, U v) {
        push(l), push(r - 1);
        bool cl = false, cr = false;
        for(l += N, r += N; l < r; l /= 2, r /= 2) {
            if(cl) calc(l - 1);
            if(cr) calc(r);
            if(l & 1) apply(l++, v), cl = true;
            if(r & 1) apply(--r, v), cr = true;
        }
        for(--l; r; l /= 2, r /= 2) {
            if(cl) calc(l);
            if(cr) calc(r);
        }
    }

    T query(ll l, ll r) {
        push(l), push(r - 1);
        T resl = idT, resr = idT;
        for(l += N, r += N; l < r; l /= 2, r /= 2) {
            if(l & 1) resl = f(resl, t[l++]);
            if(r & 1) resr = f(t[--r], resr);
        }
        return f(resl, resr);
    }
}

namespace candidate_mins { // Maintains suffix mins 
    typedef ll T;
    T id=1e17;
    T f(T a, T b) {return min(a,b);}

    T t[2 * NN];
    ll n=NN;  // array size

    void modify(ll p, T value) {  // set value at position p
      for (p+=n, t[p] = value; p /= 2;) t[p] = f(t[2*p], t[2*p+1]);
    }

    T query(ll l, ll r) { // fold f on interval [l, r)
      T resl=id, resr=id;
      for (l += n, r += n; l < r; l /= 2, r /= 2) {
        if (l&1) resl = f(resl, t[l++]);
        if (r&1) resr = f(t[--r], resr);
      }
      return f(resl, resr);
    }

    ll next_candidate_index(ll idx, ll n) { // first index < idx s.t. it's different than the current suffix min 
        auto suff = query(idx, n); 

        static vl nodes[2];
        nodes[0].reserve(32), nodes[1].reserve(32);
        nodes[0].clear(), nodes[1].clear();
        ll l = 0, r = idx;
        for (l += n, r += n; l < r; l /= 2, r /= 2) {
            if (l&1) nodes[0].push_back(l++); 
            if (r&1) nodes[1].push_back(--r);
        } 
        nodes[0].insert(nodes[0].end(), nodes[1].rbegin(), nodes[1].rend());
        for (auto it = nodes[0].rbegin(); it != nodes[0].rend(); ++it) {
            auto root = *it; if (t[root] < suff) {
                while (root < n) {
                    if (t[root * 2 + 1] < suff) root = root * 2 + 1;
                    else root = root * 2;
                }
                return root - n;
            }
        }
        return -1;
    }
}


int main(){
//    freopen("a.in", "r", stdin);
//    freopen("a.out", "w", stdout);

    ios_base::sync_with_stdio(false); cin.tie(0);
    cout << fixed << setprecision(20);
    G(n)
    ll m = 0;
    {
        map<ll, ll> rr;
        F(i, 0, n) {
            G(x) G(y) ord.emplace_back(pair(x, y), i);
            rr[x], rr[y];
        }   
        m = rr.size() - 1;
        ll x = 0;
        ll prev = 0;
        for (auto &[k, v]: rr) {
            if (x) len[x-1] = k - prev; 
            prev = k;
            v=x++;   
        }
        for (auto &[x, y]: ord) {
            x.K = rr[x.K], x.V = rr[x.V];
        }    
        sort(A(ord), [&](auto x, auto y) {
            if (x.K.K != y.K.K) return x.K.K < y.K.K;
            if (x.K.V!= y.K.V) return x.K.V > y.K.V;
            return x.V > y.V;
        });
        //F(i, 0, n) pos[ord[i].V] = i;
    }

    set<ll> active_intervals;

    F(i, 0, n) {
        candidate_mins::modify(i, ord[i].K.V), lztree::modify(i, lztree::idT);
    }
    F(i, 0, m) seg_active::modify(i, len[i]), active_intervals.insert(i);

    set<pl> lefts, rights; // {l, r} -> ord_idx
    set<ll> here; // ord_idx active

    auto ins = [&] (ll ord_idx) { 
        auto [range, i] = ord[ord_idx];
        auto [l, r] = range;
        auto initial_len = seg_active::query(l, r);
        lztree::modify(ord_idx, {initial_len, ord_idx}); // needs to be ord_idx so we can do range subtractions

        here.insert(ord_idx);
        lefts.emplace(l, ord_idx);
        rights.emplace(r, ord_idx);
    };

    auto del = [&](ll ord_idx) {
        auto [range, i] = ord[ord_idx];
        auto [l, r] = range;

        lztree::modify(ord_idx, lztree::idT); // useless again 
        candidate_mins::modify(ord_idx, candidate_mins::id); 

        // recursively find any suffix mins that changed, add to candidate

        ll cur = ord_idx;
        while (1) {
            cur = candidate_mins::next_candidate_index(cur, n);
            if (cur == -1 || here.count(cur)) break;
            ins(cur);
        }
    };

    auto sub = [&](ll idx) {
        // find the first interval with r > idx
        auto it = rights.lower_bound(pl{idx, 1e9});
        // find the first interval with l > idx  
        auto it2 = lefts.lower_bound(pl{idx, 1e9});

        ll len = seg_active::query(idx, idx + 1); assert(len);
        seg_active::modify(idx, 0);
        
        active_intervals.erase(idx);

        ll lp = it == rights.end() ? n : it->V;
        ll rp = it2 == lefts.end() ? n : it2->V;

        lztree::modify(lp, rp, -len);
    };

    {
        ll mn = 1e18;
        FD(i, n-1, -1) if (mn > ord[i].K.V) {
            mn = ord[i].K.V;          
            ins(i);      
        }
    }

    vl res;

    F(it, 0, n) {
        auto get = lztree::query(0, n);
        assert(get.V != -1);
        auto [range, idx] = ord[get.V];
        res.push_back(idx + 1);
        auto [l, r] = range;
        while (1) {
            auto it = active_intervals.lower_bound(l);
            if (it != active_intervals.end() and *it < r) {
                sub(*it);
            } else break;
        } 
        del(get.V);
    }

    for (auto x: res) cout << x << " "; cout << endl;
}

详细

Test #1:

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

input:

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

output:

1 2 5 3 4 6 

result:

ok 6 tokens

Test #2:

score: 0
Accepted
time: 0ms
memory: 26480kb

input:

4
3 7
10 14
1 6
6 11

output:

1 3 2 4 

result:

ok 4 tokens

Test #3:

score: 0
Accepted
time: 0ms
memory: 27260kb

input:

100
50 51
49 51
49 52
48 52
48 53
47 53
47 54
46 54
46 55
45 55
45 56
44 56
44 57
43 57
43 58
42 58
42 59
41 59
41 60
40 60
40 61
39 61
39 62
38 62
38 63
37 63
37 64
36 64
36 65
35 65
35 66
34 66
34 67
33 67
33 68
32 68
32 69
31 69
31 70
30 70
30 71
29 71
29 72
28 72
28 73
27 73
27 74
26 74
26 75
25...

output:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 

result:

ok 100 tokens

Test #4:

score: -100
Wrong Answer
time: 0ms
memory: 27196kb

input:

100
41 42
99 100
47 48
50 51
56 57
61 62
27 28
85 86
44 45
3 4
26 27
20 21
92 93
33 34
86 87
69 70
84 85
62 63
81 82
2 3
13 14
32 33
82 83
70 71
46 47
45 46
19 20
83 84
57 59
63 65
59 61
82 84
45 47
48 50
70 72
42 44
84 86
26 28
61 63
2 4
17 19
65 67
54 56
67 69
96 99
42 45
47 50
34 37
14 17
51 54
7...

output:

1 2 3 4 5 6 7 8 9 10 11 38 12 13 14 15 16 17 37 18 39 43 54 19 20 40 21 22 23 24 25 26 33 27 28 32 29 31 57 35 41 53 50 60 30 34 47 71 36 46 42 58 44 52 49 64 73 45 63 48 56 62 59 67 86 70 87 88 68 75 80 81 51 66 77 55 65 61 72 82 90 96 79 89 69 74 84 76 78 85 83 91 92 93 94 95 98 97 99 100 

result:

wrong answer 22nd words differ - expected: '19', found: '43'