Submission #493558

#TimeUsernameProblemLanguageResultExecution timeMemory
493558blueRoad Construction (JOI21_road_construction)C++17
100 / 100
3697 ms766140 KiB
#include <iostream> #include <vector> #include <algorithm> #include <set> using namespace std; using ll = long long; using vll = vector<ll>; using pii = pair<int, int>; const ll INF = 1'000'000'000'000LL; const int mx = 250'000; ll X[1+mx], Y[1+mx]; struct segtree { int l; int r; pair<ll, int> mn; segtree* left = NULL; segtree* right = NULL; segtree() { ; } segtree(int L, int R) { l = L; r = R; mn = {INF, l}; if(l == r) return; int m = (l+r)/2; left = new segtree(l, m); right = new segtree(m+1, r); } segtree(int L, int R, pair<ll, int> MN, segtree* LF, segtree* RG) { l = L; r = R; mn = MN; left = LF; right = RG; } segtree* set_value(int I, ll V) { if(l == r) { return new segtree(l, r, {V, I}, left, right); } else if(I <= (l+r)/2) { segtree* new_left = left->set_value(I, V); return new segtree(l, r, min(new_left->mn, right->mn), new_left, right); } else { segtree* new_right = right->set_value(I, V); return new segtree(l, r, min(left->mn, new_right->mn), left, new_right); } } pair<ll, int> rangemin(int L, int R) { if(R < l || r < L || R < L) return {2*INF, -1}; else if(L <= l && r <= R) return mn; else return min(left->rangemin(L, R), right->rangemin(L, R)); } }; int N, K; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> N >> K; vector<pii> P(N); for(int i = 0; i < N; i++) cin >> P[i].first >> P[i].second; sort(P.begin(), P.end()); for(int i = 1; i <= N; i++) { X[i] = P[i-1].first; Y[i] = P[i-1].second; } vector<int> I(N); for(int i = 0; i < N; i++) I[i] = i+1; sort(I.begin(), I.end(), [] (int p, int q) { return Y[p] < Y[q]; }); segtree* S1[1+N]; //segtree over X, sweep line over Y segtree* S2[1+N]; // S1[0] = new segtree(1, N); // S2[0] = new segtree(1, N); S1[I[0]] = new segtree(1, N); S2[I[0]] = new segtree(1, N); for(int j = 1; j < N; j++) { int i = I[j]; int i2 = I[j-1]; S1[i] = S1[i2]->set_value(i2, -X[i2] - Y[i2]); S2[i] = S2[i2]->set_value(i2, +X[i2] - Y[i2]); } set< pair<ll, int> > tbv; for(int i = 1; i <= N; i++) { tbv.insert({X[i] + Y[i] + S1[i]->rangemin(1, i-1).first, i}); tbv.insert({-X[i] + Y[i] + S2[i]->rangemin(i+1, N).first, -i}); } vector<ll> res; // cerr << "reordered points: \n"; // for(int i = 1; i <= N; i++) cerr << X[i] << ' ' << Y[i] << '\n'; for(int j = 1; j <= K; j++) { auto u = *tbv.begin(); tbv.erase(u); ll v = u.first; int i = u.second; // cerr << "j = " << j << "\n"; // cerr << "best up point: " << i << ' ' << v << '\n'; res.push_back(v); if(i > 0) { // cerr << "segtree = "; // for(int q = 1; q <= N; q++) cerr << S1[i]->rangemin(q, q).first << "/" << S1[i]->rangemin(q,q).second << ' '; // cerr << '\n'; // auto f = S1[i].rangemin(1, i-1); S1[i] = S1[i]->set_value(S1[i]->rangemin(1, i-1).second, +INF); tbv.insert({X[i] + Y[i] + S1[i]->rangemin(1, i-1).first, i}); } else { S2[-i] = S2[-i]->set_value(S2[-i]->rangemin((-i)+1, N).second, +INF); tbv.insert({-X[-i] + Y[-i] + S2[-i]->rangemin((-i)+1, N).first, i}); } } for(ll r: res) cout << r << '\n'; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...