-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathI.cpp
72 lines (71 loc) · 1.72 KB
/
I.cpp
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
#include <algorithm>
#include <functional>
#include <iostream>
#include <map>
#include <vector>
using namespace std;
int main() {
int N, M, S, D, T;
while (cin >> N >> M >> S) {
S--;
vector<pair<int, int>> b;
for (int i = 0; i < M; i++) {
cin >> D >> T;
b.push_back({-D, T-1});
}
sort(b.begin(), b.end());
map<int, int> m;
m[S] = 1;
m[(S+N/2)%N] = 0;
m[(S+(N+1)/2)%N] = -1;
auto pred = [&](map<int,int>::iterator it) { return --(it == m.begin() ?
m.end() : it); };
auto succ = [&](map<int,int>::iterator it) { ++it; return (it == m.end() ?
m.begin() : it); };
auto getAll = [&](int x) {
auto it = pred(m.upper_bound(x)), pit = it, nit = succ(it);
if (pit->first == x) pit = pred(pit);
if (nit->first != (x+1)%N) nit = it;
return make_tuple(pit, it, nit);
};
auto set = [&](int x, int d) {
auto [pit, it, nit] = getAll(x);
int xd = it->second, pd = pit->second, nd = nit->second;
if (xd == d) return;
if (d == pd) m.erase(x); else m[x] = d;
if (nd == d) m.erase((x+1)%N); else m[(x+1)%N] = nd;
};
auto swp = [&](int x) {
auto [pit, it, nit] = getAll(x);
int xd = it->second, pd = pit->second, nd = nit->second;
if (xd == 0) return;
xd = -xd; pd -= xd; nd -= xd;
if (pd == 2) { pd--; xd++; }
if (nd == -2) { nd++; xd--; }
if (pd == -2) {
pd++;
set((pit->first + (N-1))%N, pred(pit)->second - 1);
}
if (nd == 2) {
nd--;
set(succ(nit)->first, succ(nit)->second + 1);
}
set((x+N-1)%N, pd);
set(x, xd);
set((x+1)%N, nd);
};
int s = S;
for (auto [_, t] : b) {
swp(t);
if (s == t) s = (s+1)%N; else if (s == (t+1)%N) s = t;
}
vector<int> ret(N);
for (int i = 0, cur = 0, d = 0; i < N; i++) {
ret[s] = cur;
if (m.count(s)) d = m[s];
cur += d;
s = (s+1)%N;
}
for (auto x : ret) cout << x << endl;
}
}