Submission #941427

# Submission time Handle Problem Language Result Execution time Memory
941427 2024-03-08T23:10:21 Z tvladm2009 Road Construction (JOI21_road_construction) C++17
5 / 100
10000 ms 223152 KB
#include <iostream>
#include <complex>
#include <vector>
#include <string>
#include <algorithm>
#include <cstdio>
#include <numeric>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <list>
#include <cmath>
#include <bitset>
#include <cassert>
#include <queue>
#include <stack>
#include <deque>
#include <random>

using namespace std;
template<typename T1, typename T2> inline void chkmin(T1 &a, T2 b) {if (a > b) a = b;}
template<typename T1, typename T2> inline void chkmax(T1 &a, T2 b) {if (a < b) a = b;}
#define files(FILENAME) read(FILENAME); write(FILENAME)
#define read(FILENAME) freopen((FILENAME + ".in").c_str(), "r", stdin)
#define write(FILENAME) freopen((FILENAME + ".out").c_str(), "w", stdout)
#define all(c) (c).begin(), (c).end()
#define sz(c) (int)(c).size()
#define left left228
#define right right228
#define y1 y1228
#define mp make_pair
#define pb push_back
#define y2 y2228
#define rank rank228
using ll = long long;
using ld = long double; 
const string FILENAME = "input";
const int MAXN = 250228;

int n, k;
pair<ll, ll> z[MAXN];
map<ll, int> ind;
vector<ll> vals;
vector<int> occ[MAXN];

struct PST {
    struct Node {
        int result;
        Node* left;
        Node* right;

        Node (int val = 0) {
            result = val;
            left = right = NULL;
        }

        void refresh() {
            this->result = this->left->result + this->right->result;
        }
    };

    Node* build(int from, int to) {
        Node *node = new Node(0);
        if (from < to) {
            int mid = (from + to) / 2;
            node->left = build(from, mid);
            node->right = build(mid + 1, to);
        }
        return node;
    }

    Node* init(int n) {
        return build(1, n);
    }

    Node *update(Node *base, int from, int to, int x, int val) {
        if (from < to) {
            int mid = (from + to) / 2;
            Node* newNode = new Node();
            (*newNode) = (*base);
            if (x <= mid) {
                newNode->left = update(base->left, from, mid, x, val);
            } else {
                newNode->right = update(base->right, mid + 1, to, x, val);
            }
            newNode->refresh();
            return newNode;
        } else {
            return (new Node(base->result + val));
        }
    }
    
    int query(Node *node, int from, int to, int x, int y) {
        if (from == x && to == y) {
            return node->result;
        } else {
            int mid = (from + to) / 2;
            if (x <= mid && y <= mid) {
                return query(node->left, from, mid, x, y);
            } else if (mid + 1 <= x && mid + 1 <= y)  {
                return query(node->right, mid + 1, to, x, y);
            } else {
                return query(node->left, from, mid, x, mid) + query(node->right, mid + 1, to, mid + 1, y);
            }
        }
    }

    Node* version[MAXN];
    int n;

    void buildVersions(int nn) {
        n = nn;
        Node *partial = init(n);
        version[0] = partial;
        for (int i = 1; i <= n; i++) {
            for (auto pos: occ[i]) {
                partial = update(partial, 1, n, pos, +1);
            }
            version[i] = partial;
        }
    }

    int get(int when, int l, int r) {
        return query(version[when], 1, n, l, r);
    }
};

PST pst;

struct Query {
	ll l;
	ll r;
	ll x;	
	ll y;
};

ll getsmaller(ll x, ll ql, ll qr) {
    int l = 0, r = n - 1, when = 0;
    while (l <= r) {
        int m = (l + r) / 2;
        if (vals[m] <= x) {
            when = ind[vals[m]];
            l = m + 1;
        } else {
            r = m - 1;
        }
    } 
    return pst.get(when, ql, qr);
}

ll get(ll m) {
	vector<Query> queries;
	for (int i = 0; i < n; i++) {
		int l = 0, r = i - 1, pos = i;
		while (l <= r) {
			int mid = (l + r) >> 1;
			if (z[i].first - z[mid].first <= m) {
				r = mid - 1;
				pos = mid;
			} else {
				l = mid + 1;
			}
		}
		queries.pb({pos, i - 1, z[i].second - m, z[i].second + m});
	}
	ll res = 0;
	for (auto it: queries) {
		ll l = it.l; 
		ll r = it.r;
		ll x = it.x;
		ll y = it.y; 
        l++;
        r++;
        if (l > r || l < 0) {
            continue;
        }
		res += getsmaller(y, l, r) - getsmaller(x - 1, l, r);
	}
	return res;
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	//read(FILENAME);
	cin >> n >> k;
	for (int i = 0; i < n; i++) {
		int x, y;
		cin >> x >> y;
		z[i] = mp(x + y, x - y);
	}
	sort(z, z + n);
    {
        for (int i = 0; i < n; i++) {
            vals.pb(z[i].second);
        }
        sort(all(vals));
        int cnt = 0;
        for (int i = 0; i < n; i++) {
            if (ind[vals[i]] == 0) {
                ind[vals[i]] = ++cnt;
            }
        }
        for (int i = 0; i < n; i++) {
             occ[ind[z[i].second]].pb(i + 1);
        }
    }  
    pst.buildVersions(n);
    ll l = 0, r = 4e9, val = 0;
	while (l <= r) {
		ll m = (l + r) / 2;
		if (get(m) >= k) {
			val = m;
			r = m - 1;
		} else {
			l = m + 1;
		}
	}

    auto dist = [&](int i, int j) {
        return max(abs(z[i].first - z[j].first), abs(z[i].second - z[j].second));
    };
    
    vector<ll> sol;
    set<pair<ll, int>> s;
    int ptr = 0;
	for (int i = 0; i < n; i++) {
        s.insert(mp(z[i].second, i));
        while (ptr < i && z[i].first - z[ptr].first >= val) {
            s.erase(mp(z[ptr].second, ptr));
            ptr++;
        }
        auto it = s.find(mp(z[i].second, i));
        auto pos = it;
        while (pos != s.begin() && z[i].second - pos->first < val) {
            if (pos->second != i) {
                sol.pb(dist(pos->second, i));
            }
            pos--;
        }
        if (z[i].second - pos->first < val) {
            if (pos->second != i) {
                sol.pb(dist(pos->second, i));
            }
        }
        pos = it;
        while (pos != s.end() && pos->first - z[i].second < val) {
            if (pos->second != i) {
                sol.pb(dist(pos->second, i));
            }
            pos++;
        }
    }
    sort(all(sol));
    assert(sz(sol) <= k);
    while (sz(sol) < k) {
        sol.pb(val);
    }
    for (auto y: sol) {
        cout << y << '\n';
    }
    return 0;
}

# Verdict Execution time Memory Grader output
1 Correct 52 ms 13860 KB Output is correct
2 Correct 62 ms 13804 KB Output is correct
3 Correct 41 ms 13676 KB Output is correct
4 Correct 39 ms 13756 KB Output is correct
5 Correct 44 ms 12760 KB Output is correct
6 Correct 10 ms 9052 KB Output is correct
# Verdict Execution time Memory Grader output
1 Execution timed out 10040 ms 221240 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Execution timed out 10045 ms 223152 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Execution timed out 10045 ms 223152 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 52 ms 13860 KB Output is correct
2 Correct 62 ms 13804 KB Output is correct
3 Correct 41 ms 13676 KB Output is correct
4 Correct 39 ms 13756 KB Output is correct
5 Correct 44 ms 12760 KB Output is correct
6 Correct 10 ms 9052 KB Output is correct
7 Execution timed out 10045 ms 92756 KB Time limit exceeded
8 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 52 ms 13860 KB Output is correct
2 Correct 62 ms 13804 KB Output is correct
3 Correct 41 ms 13676 KB Output is correct
4 Correct 39 ms 13756 KB Output is correct
5 Correct 44 ms 12760 KB Output is correct
6 Correct 10 ms 9052 KB Output is correct
7 Execution timed out 10040 ms 221240 KB Time limit exceeded
8 Halted 0 ms 0 KB -