QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#450959#8793. Toiletsucup-team173WA 388ms58636kbC++208.1kb2024-06-22 19:56:362024-06-22 19:56:36

Judging History

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

  • [2024-06-22 19:56:36]
  • 评测
  • 测评结果:WA
  • 用时:388ms
  • 内存:58636kb
  • [2024-06-22 19:56:36]
  • 提交

answer

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

#ifdef ONLINE_JUDGE
constexpr bool debug = false;
#else
constexpr bool debug = true;
#endif

using i64 = long long;

struct event {
    i64 time, pos, dur;
    int type, dir, id;
    /*
              case                      available
    type = 0: toilet emerge         pos
    type = 1: person emerge         pos, dur, dir, id
    type = 2: person finds toilet   pos, id
    */
    bool operator < (const event &e) const {
        if(time != e.time) return time < e.time;
        if(type != e.type) return type < e.type;
        if(type) return id < e.id;
        else return pos < e.pos;
    }
    bool operator == (const event &e) const {
        return time == e.time && type == e.type && pos == e.pos && dur == e.dur && dir == e.dir && id == e.id;
    }
};

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    i64 n, m, L;
    cin >> n >> m >> L;
    set<i64> toilet;
    map<i64, set<int>> person_dir[2]; // 1: pos  0: neg
    map<i64, array<int, 2>> toilet_near;
    for(int i = 0; i < m; i++) {
        i64 x;
        cin >> x;
        toilet.insert(x);
        toilet_near[x] = {0, 0};
    }
    set<event> q;
    vector<array<i64, 4>> person(n + 1); // <time, pos, dir, dur>
    vector<event> person_near(n + 1);
    for(int i = 1; i <= n; i++) {
        int t, p, d;
        string s;
        cin >> t >> p >> s >> d;
        person_near[i].pos = -1;
        if(s == "+") {
            q.insert({t, p, d, 1, 1, i});
            person[i] = {t, p, 1, d};
        } else {
            q.insert({t, p, d, 1, 0, i});
            person[i] = {t, p, 0, d};
        }
    }
    auto norm = [&](i64 x) { return (x % L + L) % L; };
    auto dist = [&](int id, i64 pos, i64 ti) -> i64 { // time to go _pos_ for person _id_ at time _ti_
        if(pos == -1) return 1e18;
        ti -= person[id][0];
        return person[id][2] == 1 ? norm(pos - ti - person[id][1]) : norm(person[id][1] - ti - pos);
    };
    auto find_right = [&](set<i64> &st, i64 x) -> i64 {
        if(st.empty()) return -1;
        auto it = st.lower_bound(x);
        if(it == st.end()) return *st.begin();
        return *it;
    };
    auto find_left = [&](set<i64> &st, i64 x) -> i64 {
        if(st.empty()) return -1;
        auto it = st.upper_bound(x);
        if(it == st.begin()) return *st.rbegin();
        return *prev(it);
    };
    auto find_right_id = [&](map<i64, set<int>> &st, i64 x) -> int {
        if(st.empty()) return -1;
        auto it = st.lower_bound(x);
        if(it == st.end()) return *st.begin()->second.begin();
        return *it->second.begin();
    };
    auto find_left_id = [&](map<i64, set<int>> &st, i64 x) -> int {
        if(st.empty()) return -1;
        auto it = st.upper_bound(x);
        if(it == st.begin()) return *st.rbegin()->second.begin();
        return *prev(it)->second.begin();
    };
    i64 cnt = 0;
    vector<pair<i64, i64>> ans(n + 1);
    auto link_person = [&](i64 ti, i64 pos, i64 dur, i64 ty, int dir, int id) { // try to link person _id_ to toilet and maintain the queue
        i64 near = dir == 1 ? find_right(toilet, norm(pos + ti - person[id][0])) : find_left(toilet, norm(pos - ti + person[id][0]));
        if(debug) cerr << "     near = " << near << '\n';
        if(near == -1) return;
        int o = toilet_near[near][!dir];
        if(o == 0) {
            toilet_near[near][!dir] = id;
            person_near[id] = {ti + dist(id, near, ti), near, dur, 2, dir, id};
            q.insert(person_near[id]);
        } else {
            if(debug) cerr << "     dist1 = " << dist(id, near, ti) << ' ' << "dist2 = " << dist(o, near, ti) << '\n';
            if(make_pair(dist(id, near, ti), id) < make_pair(dist(o, near, ti), o)) {
                q.erase(person_near[o]); // should I modify person_near[o] ?
                person_near[o] = {0, -1, 0, 0, 0, 0};
                toilet_near[near][!dir] = id;
                person_near[id] = {ti + dist(id, near, ti), near, dur, 2, dir, id};
                q.insert(person_near[id]);
            }
        }
    };
    while(cnt < n) {
        if(debug) cerr << "-----------------------------------\n";
        auto [ti, pos, dur, ty, dir, id] = *q.begin();
        q.erase(q.begin());
        if(ty == 0) { // toilet emerge
            toilet.insert(pos);
            int left = find_left_id(person_dir[1], norm(pos - ti));
            int right = find_right_id(person_dir[0], norm(pos + ti));
            if(debug) cerr << "     dist1 = " << dist(left, pos, ti) << ' ' << "dist2 = " << dist(left, person_near[left].pos, ti) << '\n';
            if(left != -1 && dist(left, pos, ti) < dist(left, person_near[left].pos, ti)) {
                q.erase(person_near[left]);
                toilet_near[person_near[left].pos][0] = 0;
                toilet_near[pos][0] = left;
                person_near[left] = {ti + dist(left, pos, ti), pos, 0, 2, 0, left};
                q.insert(person_near[left]);
            }
            if(right != -1 && dist(right, pos, ti) < dist(right, person_near[right].pos, ti)) {
                q.erase(person_near[right]);
                toilet_near[person_near[right].pos][1] = 0;
                toilet_near[pos][1] = right;
                person_near[right] = {ti + dist(right, pos, ti), pos, 0, 2, 0, right};
                q.insert(person_near[right]);
            }
        } else if(ty == 1) { // person emerge
            person_dir[dir][norm(dir == 1 ? pos - ti : pos + ti)].insert(id);
            link_person(ti, pos, dur, ty, dir, id);
        } else { // person finds toilet
            dur = person[id][3], dir = person[id][2];
            ans[id] = {pos, ti}, cnt++;
            i64 pp = norm(dir == 1 ? pos - ti : pos + ti);
            person_dir[dir][pp].erase(id);
            if(person_dir[dir][pp].empty()) person_dir[dir].erase(pp);
            int o1 = toilet_near[pos][dir];
            pp = norm(dir == 1 ? person[id][1] - person[id][0] : person[id][1] + person[id][0]);
            int o2 = dir == 1 ? find_left_id(person_dir[1], pp) : find_right_id(person_dir[0], pp);
            toilet_near[pos] = {0, 0};
            toilet.erase(pos);
            q.insert({ti + dur, pos, 0, 0, 0, 0});
            if(o1) { // no need to check o != id
                q.erase(person_near[o1]);
                person_near[o1] = {0, -1, 0, 0, 0, 0};
                link_person(ti, person[o1][1], person[o1][3], 1, person[o1][2], o1);
            }
            if(o2 != -1) {
                link_person(ti, person[o2][1], person[o2][3], 1, person[o2][2], o2);
            }
        }
        if(!debug) continue;
        cerr << "ti = " << ti << ' ' << "pos = " << pos << ' ' << "dur = " << dur << ' ' << "ty = " << ty << ' ' << "dir = " << dir << ' ' << "id = " << id << '\n';
        cerr << "toilet: ";
        for(auto x : toilet) cerr << x << ' ';
        cerr << '\n';
        cerr << "person_dir[0]: ";
        for(auto [x, y] : person_dir[0]) {
            cerr << x << "(";
            for(auto z : y) cerr << z << (z == *y.rbegin() ? "" : ",");
            cerr << ") ";
        }
        cerr << '\n';
        cerr << "person_dir[1]: ";
        for(auto [x, y] : person_dir[1]) {
            cerr << x << "(";
            for(auto z : y) cerr << z << (z == *y.rbegin() ? "" : ",");
            cerr << ") ";
        }
        cerr << '\n';
        cerr << "events:\n";
        cerr << "tim pos dur typ dir  id\n";
        for(auto x : q) {
            cerr << setw(3) << x.time << ' ' << setw(3) << x.pos << ' '
                 << setw(3) << x.dur << ' ' << setw(3) << x.type << ' '
                 << setw(3) << x.dir << ' ' << setw(3) << x.id << '\n';
        }
    }
    for(int i = 1; i <= n; i++) {
        cout << ans[i].first << ' ' << ans[i].second << '\n';
    }
    /*
    i64 time, pos, dur;
    int type, dir, id;
              case                      available
    type = 0: toilet emerge         pos
    type = 1: person emerge         pos, dur, dir, id
    type = 2: person finds toilet   pos, id
    */
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

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

input:

5 3 45
10 20 30
0 0 + 200
2 5 + 10
20 40 - 100
21 16 + 10
50 0 + 22

output:

20 20
10 7
30 30
10 60
10 105

result:

ok 10 numbers

Test #2:

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

input:

1 1 1
0
0 0 - 1

output:

0 0

result:

ok 2 number(s): "0 0"

Test #3:

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

input:

5 3 33
3 24 23
12 24 - 9
16 28 - 1
17 27 - 9
19 26 - 5
32 22 - 2

output:

24 12
23 21
3 41
24 21
3 51

result:

ok 10 numbers

Test #4:

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

input:

4 5 6
1 3 4 2 0
2 1 + 2
7 3 + 6
9 0 + 9
10 1 - 6

output:

1 2
3 7
0 9
1 10

result:

ok 8 numbers

Test #5:

score: 0
Accepted
time: 1ms
memory: 3760kb

input:

736 30 100500
99382 85511 67593 53450 55531 9959 37170 57546 52666 62342 50707 71285 65933 19874 2092 100255 23965 83091 45652 64171 100128 19518 21445 96069 79781 52642 37943 95321 97569 69154
0 44619 + 7052
2 72499 + 29247
3 53785 - 35614
5 81887 + 64475
7 8561 + 31641
8 95471 - 22654
9 61040 - 44...

output:

53450 310331
95321 22824
53450 338
67593 186711
23965 718911
95321 158
83091 580958
62342 71243
50707 602820
83091 183
2092 375130
96069 552638
100128 541370
64171 5285
50707 288492
45652 795873
2092 284
85511 720931
55531 713428
53450 483192
69154 5302
83091 155808
57546 351069
2092 231938
85511 60...

result:

ok 1472 numbers

Test #6:

score: -100
Wrong Answer
time: 388ms
memory: 58636kb

input:

200000 200000 200000
45589 41206 151226 67898 73967 140984 73325 186330 35522 72131 147731 139390 123121 817 198939 98824 55631 84079 28987 108012 22006 143408 11442 195253 179662 189693 142207 99819 103750 166626 140235 140358 148893 170212 14967 98607 193895 19535 87565 166568 179135 11569 109260 ...

output:

99245 0
99244 1
99243 2
99242 3
99241 4
99240 5
99239 6
99238 7
99237 8
99236 9
99235 10
99234 11
99233 12
99232 13
99231 14
99230 15
99229 16
99228 17
99227 18
99226 19
99225 20
99224 21
99223 22
99222 23
99221 24
99220 25
99219 26
99218 27
99217 28
99216 29
99215 30
99214 31
99213 32
99212 33
9921...

result:

wrong answer 3rd numbers differ - expected: '159669', found: '99244'