Submission #434851

#TimeUsernameProblemLanguageResultExecution timeMemory
434851blueRoad Construction (JOI21_road_construction)C++17
12 / 100
10100 ms30244 KiB
#include <iostream> #include <vector> #include <algorithm> #include <cmath> #include <set> using namespace std; /* 1. Normalize Y coordinates Binary search for K'th smallest distance: WLOG x[1] <= ... <= x[N] The cost for the point i and the point j is (x[j] - x[i]) + |y[j] - y[i]|. y[i] < y[j] (x[j] + y[j]) - (x[i] + y[i]) Segtree S y[i] >= y[j] (x[j] - y[j]) - (x[i] - y[i]) Segtree T Maintain two segment trees: In one store the x[i] + y[i] values, in the other store the x[i] - y[i] values. For each point compute the normalized Y coordinate. */ const long long INF = 1'000'000'000'000; const int maxN = 250000; struct segtree { pair<int, long long>* v; //range max segtree() { v = new pair<int, long long>[600001]; } void build_segtree(int i, int L, int R) { v[i] = make_pair(L, -INF); if(L == R) return; int m = (L+R)/2; build_segtree(2*i, L, m); build_segtree(2*i+1, m+1, R); } void update(int i, int l, int r, int I, long long V) { if(I < l || r < I) return; else if(l == r) v[i] = make_pair(l, V); else { update(2*i, l, (l+r)/2, I, V); update(2*i+1, (l+r)/2+1, r, I, V); pair<int, long long> LP = v[2*i]; pair<int, long long> RP = v[2*i + 1]; if(LP.second > RP.second) v[i] = LP; else v[i] = RP; } } pair<int, long long> rangemax(int i, int l, int r, int L, int R) { if(R < l || r < L) return make_pair(-1, -INF); else if(L <= l && r <= R) return v[i]; else { pair<int, long long> LP = rangemax(2*i, l, (l+r)/2, L, R); pair<int, long long> RP = rangemax(2*i + 1, (l+r)/2+1, r, L, R); if(LP.second > RP.second) return LP; else return RP; } } }; int N, K; struct point { long long X; long long Y; int Yindex; }; vector<point> P; int main() { // cerr << "hello\n"; ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> N >> K; P = vector<point>(N); for(int i = 0; i < N; i++) cin >> P[i].X >> P[i].Y; sort(P.begin(), P.end(), [] (point A, point B) { return A.Y < B.Y; }); for(int i = 0; i < N; i++) P[i].Yindex = i+1; sort(P.begin(), P.end(), [] (point A, point B) { return A.X < B.X; }); // cerr << "check0\n"; // for(point p:P) cerr << p.X << ' ' << p.Y << ' ' << p.Yindex << '\n'; segtree S, T; S.build_segtree(1, 1, N); T.build_segtree(1, 1, N); // cerr << "check1\n"; long long lo = 0, hi = 4'000'000'000LL; vector<long long> res; while(1) { long long Kval = (lo+hi)/2; res.clear(); for(int i = 1; i <= N; i++) { S.update(1, 1, N, i, -INF); T.update(1, 1, N, i, -INF); } // cerr << "searching " << lo << ' ' << hi << '\n'; for(point p:P) { vector< pair<int, long long> > updates; while(res.size() < K) { pair<int, long long> Q = S.rangemax(1, 1, N, 1, p.Yindex); if(Q.second <= -INF) break; if((p.X + p.Y) - Q.second > Kval) break; res.push_back((p.X + p.Y) - Q.second); S.update(1, 1, N, Q.first, -INF); updates.push_back(Q); } for(pair<int, long long> u: updates) S.update(1, 1, N, u.first, u.second); updates.clear(); while(res.size() < K) { pair<int, long long> Q = T.rangemax(1, 1, N, p.Yindex+1, N); if(Q.second <= -INF) break; if((p.X - p.Y) - Q.second > Kval) break; res.push_back((p.X - p.Y) - Q.second); T.update(1, 1, N, Q.first, -INF); updates.push_back(Q); } for(pair<int, long long> u: updates) T.update(1, 1, N, u.first, u.second); updates.clear(); S.update(1, 1, N, p.Yindex, p.X + p.Y); T.update(1, 1, N, p.Yindex, p.X - p.Y); if(res.size() >= K) break; } sort(res.begin(), res.end()); if(lo == hi) { break; } else if(res.size() >= K) hi = min(res[K-1], Kval); else lo = Kval + 1; } for(long long r:res) cout << r << '\n'; }

Compilation message (stderr)

road_construction.cpp: In function 'int main()':
road_construction.cpp:139:30: warning: comparison of integer expressions of different signedness: 'std::vector<long long int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  139 |             while(res.size() < K)
      |                   ~~~~~~~~~~~^~~
road_construction.cpp:163:30: warning: comparison of integer expressions of different signedness: 'std::vector<long long int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  163 |             while(res.size() < K)
      |                   ~~~~~~~~~~~^~~
road_construction.cpp:190:27: warning: comparison of integer expressions of different signedness: 'std::vector<long long int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  190 |             if(res.size() >= K) break;
      |                ~~~~~~~~~~~^~~~
road_construction.cpp:198:28: warning: comparison of integer expressions of different signedness: 'std::vector<long long int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  198 |         else if(res.size() >= K) hi = min(res[K-1], Kval);
      |                 ~~~~~~~~~~~^~~~
#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...