Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define all(x) (x).begin(),(x).end()
- #define N 100100
- using namespace std;
- using ll = long long;
- int Right[N];
- int Left[N];
- struct StrangeTree {
- vector<vector<int>> t;
- StrangeTree(int n, vector<int>& cans) : t(n * 4) {}
- void Update(int v, int tl, int tr, int l, int r, int ind) {
- if (tl >= r || tr <= l) return;
- if (tl >= l && tr <= r) {
- t[v].push_back(ind);
- } else {
- int tm = (tl + tr) / 2;
- Update(v * 2 + 1, tl, tm, l, r, ind);
- Update(v * 2 + 2, tm, tr, l, r, ind);
- }
- }
- void Build(int v, int tl, int tr) {
- for (int i = 0; i < int(size(t)); i++) {
- sort(all(t[i]));
- }
- }
- bool Get(int v, int tl, int tr, int index, int l, int r) {
- int left = 0;
- int right = int(size(t[v])) - 1;
- int mid;
- int realLeft = N;
- int realRight = -1;
- while (left <= right) {
- mid = (left + right) / 2;
- if (t[v][mid] >= l) {
- realLeft = mid;
- right = mid - 1;
- } else {
- left = mid + 1;
- }
- }
- left = 0;
- right = int(size(t[v])) - 1;
- while (left <= right) {
- mid = (left + right) / 2;
- if (t[v][mid] <= r) {
- realRight = mid;
- left = mid + 1;
- } else {
- right = mid - 1;
- }
- }
- for (int i = realLeft; i <= realRight; i++) {
- if (t[v][i] != index) {
- return true;
- }
- }
- if (tl + 1 == tr) {
- return false;
- } else {
- int tm = (tl + tr) / 2;
- if (index < tm) {
- return Get(v * 2 + 1, tl, tm, index, l, r);
- } else {
- return Get(v * 2 + 2, tm, tr, index, l, r);
- }
- }
- }
- };
- struct Event {
- int type;
- int x;
- int i;
- Event(int ctype, int cx, int ci)
- : type(ctype)
- , x(cx)
- , i(ci)
- {
- }
- bool operator < (const Event& o) {
- if (x != o.x) return x < o.x;
- if (type != o.type) return type < o.type;
- return i < o.i;
- }
- bool operator > (const Event& o) {
- if (x != o.x) return x > o.x;
- if (type != o.type) return type > o.type;
- return i > o.i;
- }
- };
- int main() {
- ios_base::sync_with_stdio(false);
- cin.tie(nullptr);
- cout.tie(nullptr);
- int n;
- cin >> n;
- vector<pair<int,int>> arr(n);
- vector<int> l(n), r(n);
- for (int i = 0; i < n; i++) {
- cin >> arr[i].first;
- arr[i].second = i;
- }
- sort(all(arr));
- for (int i = 0; i < n; i++) {
- cin >> l[i] >> r[i];
- }
- {
- for (int i = 0; i < n; i++) {
- int left = 0;
- int right = n - 1;
- int mid;
- int realL = n;
- while (left <= right) {
- mid = (left + right) / 2;
- if (arr[mid].first >= l[i]) {
- realL = mid;
- right = mid - 1;
- } else {
- left = mid + 1;
- }
- }
- left = 0;
- right = n - 1;
- int realR = -1;
- while (left <= right) {
- mid = (left + right) / 2;
- if (arr[mid].first <= r[i]) {
- realR = mid;
- left = mid + 1;
- } else {
- right = mid - 1;
- }
- }
- Left[i] = realL;
- Right[i] = realR;
- }
- }
- vector<Event> events;
- const int START = 1;
- const int FINISH = 2;
- for (int i = 0; i < n; i++) {
- events.push_back(Event{START, Left[i], i});
- events.push_back(Event{FINISH, Right[i], i});
- }
- sort(all(events));
- set<pair<int,int>> setik;
- int index = 0;
- vector<int> mt(n, -1);
- int res = 0;
- vector<bool> used(n, false);
- for (int x = 0; x < n; x++) {
- while (index < int(size(events)) &&
- events[index].x == x &&
- events[index].type == START) {
- setik.insert({Right[events[index].i], events[index].i});
- index++;
- }
- if (size(setik) == 0U) {
- cout << "Let's search for another office." << endl;
- return 0;
- }
- auto [right, ind] = *setik.begin();
- setik.erase(setik.begin());
- if (right < x) {
- break;
- }
- mt[x] = ind;
- used[ind] = true;
- res++;
- while (index < int(size(events)) &&
- events[index].x == x &&
- events[index].type == FINISH) {
- if (used[ind]) {
- index++;
- } else {
- cout << "Let's search for another office." << endl;
- return 0;
- }
- }
- }
- if (res < n) {
- cout << "Let's search for another office." << endl;
- return 0;
- }
- vector<int> ans(n);
- for (int i = 0; i < n; i++) {
- ans[mt[i]] = i;
- }
- StrangeTree tree(n, ans);
- for (int i = 0; i < n; i++) {
- tree.Update(0, 0, n, Left[i], Right[i] + 1, ans[i]);
- }
- tree.Build(0, 0, n);
- for (int i = 0; i < n; i++) {
- if (tree.Get(0, 0, n, ans[i], Left[i], Right[i])) {
- cout << "Ask Shiftman for help." << " " << endl;
- return 0;
- }
- }
- cout << "Perfect!" << endl;
- for (int i = 0; i < n; i++) {
- cout << arr[ans[i]].second + 1 << ' ';
- }
- cout << endl;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement