Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Problem : Problem 1. A Pie for a Pie
- // Contest : USACO 2017 December Contest, Gold
- // URL : http://usaco.org/index.php?page=viewproblem2&cpid=765
- // Memory Limit : 256 MB
- // Time Limit : 4000 ms
- // Powered by CP Editor (https://github.com/cpeditor/cp-editor)
- #include <bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- typedef pair<int, int> pii;
- const int N = 100100;
- const int BASE = 1<<17;
- const int inf = 1e9 + 10;
- int n, D;
- int data[2][2][N];
- int order[2][N];
- int invorder[2][N];
- int ans[2][N];
- struct segtree {
- struct Node {
- int dist, node, lazy;
- bool disabled;
- Node() {
- dist = lazy = inf;
- node = -1;
- disabled = false;
- }
- inline void merge(Node& l, Node& r) {
- disabled = false;
- if (l.disabled && r.disabled) {
- dist = inf, node = -1;
- disabled = true;
- } else if (l.disabled) {
- dist = r.dist, node = r.node;
- } else if (r.disabled) {
- dist = l.dist, node = l.node;
- } else if (l.dist < r.dist) {
- dist = l.dist, node = l.node;
- } else {
- dist = r.dist, node = r.node;
- }
- }
- inline void push(Node& l, Node& r) {
- l.receive(lazy);
- r.receive(lazy);
- lazy = inf;
- }
- inline void receive(int lz) {
- if (!disabled) {
- dist = min(dist, lz);
- lazy = min(lazy, lz);
- }
- }
- };
- Node tree[2*BASE];
- void build(int v, int tl, int tr) {
- if (tl == tr) {
- tree[v].dist = inf;
- tree[v].node = tl;
- } else {
- int tm = (tl + tr) / 2;
- build(2*v, tl, tm);
- build(2*v+1, tm+1, tr);
- tree[v].merge(tree[2*v], tree[2*v+1]);
- }
- }
- void update(int v, int tl, int tr, int l, int r, int val) {
- if (l > r || tree[v].disabled) return;
- if (l == tl && tr == r) {
- tree[v].receive(val);
- return;
- }
- tree[v].push(tree[2*v], tree[2*v+1]);
- int tm = (tl + tr) / 2;
- update(2*v, tl, tm, l, min(r, tm), val);
- update(2*v+1, tm+1, tr, max(l, tm+1), r, val);
- tree[v].merge(tree[2*v], tree[2*v+1]);
- }
- void disable(int v, int tl, int tr, int pos) {
- if (tl == tr) {
- tree[v].disabled = true;
- return;
- }
- tree[v].push(tree[2*v], tree[2*v+1]);
- int tm = (tl + tr) / 2;
- if (pos <= tm) {
- disable(2*v, tl, tm, pos);
- } else {
- disable(2*v+1, tm+1, tr, pos);
- }
- tree[v].merge(tree[2*v], tree[2*v+1]);
- }
- } tree[2];
- int main() {
- ios::sync_with_stdio(false);
- cin.tie(0);
- #ifndef _DEBUG
- freopen("piepie.in", "r", stdin);
- freopen("piepie.out", "w", stdout);
- #endif
- cin >> n >> D;
- for (int k = 0; k < 2; ++k) {
- tree[k].build(1, 0, n-1);
- }
- for (int k = 0; k < 2; ++k) {
- for (int i = 0; i < n; ++i) {
- for (int j = 0; j < 2; ++j) {
- cin >> data[k][j][i];
- }
- ans[k][i] = inf;
- order[k][i] = i;
- }
- sort(order[k], order[k]+n, [&] (int i, int j) {
- return data[k][k][i] < data[k][k][j];
- });
- for (int i = 0; i < n; ++i) {
- int u = order[k][i];
- invorder[k][u] = i;
- if (data[k][1-k][u] == 0) {
- tree[k].update(1, 0, n-1, i, i, 0);
- }
- }
- }
- /*
- for (int k = 0; k < 2; ++k) {
- for (int i = 0; i < n; ++i) {
- for (int j = 0; j < 2; ++j) {
- cout << "data["<<k<<"]["<<j<<"]["<<i<<"] = "<<data[k][j][i]<<"\n";
- }
- }
- }
- */
- while (true) {
- int k = -1, i = -1, dist = inf;
- for (int k1 = 0; k1 < 2; ++k1) {
- if (tree[k1].tree[1].disabled) continue;
- int i1 = tree[k1].tree[1].node;
- int dist1 = tree[k1].tree[1].dist;
- if (dist1 < dist) {
- k = k1;
- i = i1;
- dist = dist1;
- }
- }
- if (dist == inf) break;
- tree[k].disable(1, 0, n-1, i);
- int u = order[k][i];
- ans[k][u] = dist;
- int x = data[k][1-k][u];
- int l = n, r = -1;
- int lo, hi, mid;
- lo = 0, hi = n-1;
- while (lo <= hi) {
- mid = (lo + hi) / 2;
- int v = order[1-k][mid];
- if (data[1-k][1-k][v] >= x - D) {
- l = mid;
- hi = mid-1;
- } else {
- lo = mid+1;
- }
- }
- lo = 0, hi = n-1;
- while (lo <= hi) {
- mid = (lo + hi) / 2;
- int v = order[1-k][mid];
- if (data[1-k][1-k][v] <= x) {
- r = mid;
- lo = mid+1;
- } else {
- hi = mid-1;
- }
- }
- //cout << "k="<<k<<" i="<<i<<" d="<<dist<<" u="<<u<<" x="<<x<<" l="<<l<<" r="<<r<<"\n";
- if (l <= r) {
- tree[1-k].update(1, 0, n-1, l, r, dist+1);
- }
- }
- for (int i = 0; i < n; ++i) {
- if (ans[0][i] >= inf) {
- cout << -1 << '\n';
- } else {
- cout << ans[0][i]+1 << '\n';
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement