Submission #64282

#TimeUsernameProblemLanguageResultExecution timeMemory
64282FLDutchmanBulldozer (JOI17_bulldozer)C++14
100 / 100
1149 ms132288 KiB
#include <bits/stdc++.h> using namespace std; #define mp make_pair #define pb push_back #define fst first #define snd second #define int long long #define fast_io() ios::sync_with_stdio(false) #define FOR(i, l, r) for(int i = (l); i < (r); i++) typedef long long ll; typedef pair<ll, ll> ii; typedef vector<int> vi; typedef vector<ii> vii; typedef vector<vi> vvi; typedef set<int> si; typedef double ld; typedef pair<ld, ld> dd; const ll INF = 1000000000000000000LL; const int NMAX = 1e6+4; const int mod = 1e9+7; const ld eps = 1e-10; const ld PI = acos(-1); struct point{ int x, y, w, i; const bool operator< (const point &p){ return mp(x, y) < mp(p.x, p.y); } }; int N; vector<point> pts; vi position; struct event{ int i, j; int x1, y1, x2, y2; int dx, dy; event(int a, int b) : i(a), j(b) { if(pts[j].x < pts[i].x) swap(i, j); x1 = pts[i].x, y1 = pts[i].y; x2 = pts[j].x, y2 = pts[j].y; dx = x2 - x1; dy = y2 - y1; } event(){} friend bool operator< ( const event &e1, const event &e2){ int s = e1.dy * e2.dx - e2.dy * e1.dx; if(s != 0) return s < 0; return e1.dx * (e1.y1 - e2.y1) + e1.dy * (e2.x1 - e1.x1) < 0; } }; bool par(const event &e1, const event &e2){ return e1.dy * e2.dx == e2.dy * e1.dx; } bool col(const event &e1, const event &e2){ return !(e1 < e2) and !(e2 < e1); } vi tsum, tmin, tmax, tbest; void update(int n){ int l = n<<1, r = l|1; tsum[n] = tsum[l] + tsum[r]; tmin[n] = min(tmin[l], tsum[l] + tmin[r]); tmax[n] = max(tmax[l], tsum[l] + tmax[r]); tbest[n] = max(tsum[l] + tmax[r] - tmin[l], max(tbest[l], tbest[r])); } void buildtree(int lb, int rb, int n = 1){ if(lb+1 == rb) { int w = pts[lb].w; tsum[n] = w; tmin[n] = min(0LL, w); tbest[n] = tmax[n] = max(0LL, w); } else { int mb = (lb+rb)/2; buildtree(lb, mb, n<<1); buildtree(mb, rb, n<<1|1); update(n); } } void modify(int i, int w, int lb, int rb, int n = 1){ if(lb+1 == rb){ tsum[n] = w; tmin[n] = min(0LL, w); tbest[n] = tmax[n] = max(0LL, w); } else { int mb = (lb+rb)/2; if(i < mb) modify(i, w, lb, mb, n<<1); else modify(i, w, mb, rb, n<<1|1); update(n); } } int getbest(){ return tbest[1]; } /* int ms(){ using namespace std::chrono; int m = duration_cast< milliseconds >( system_clock::now().time_since_epoch() ).count(); return m; }*/ vector<event> events; //int t0; signed main(){ //t0 = ms(); fast_io(); cin >> N; tmin.assign(4*N, 0); tmax.assign(4*N, 0); tsum.assign(4*N, 0); tbest.assign(4*N, 0); position.assign(N, 0); FOR(i, 0, N){ int x,y,w; cin >> x >> y >> w; pts.pb({x, y, w, y}); } /*int t = ms(); cout << "Reading " << t - t0 << endl; t0 = t;*/ sort(pts.begin(), pts.end()); /*t = ms(); cout << "Sorting points " << t - t0 << endl; t0 = t;*/ FOR(i, 0, N) pts[i].i = i; FOR(i, 0, N) position[pts[i].i] = i; buildtree(0, N); FOR(i, 0, N) FOR(j, i+1, N) events.pb(event(i, j)); sort(events.begin(), events.end()); /*t = ms(); cout << "Sorting events " << t - t0 << endl; t0 = t; */ // each block contains parallel events //cout << "Sorted events" << endl; int l = N, r = 0; int best = getbest(); FOR(i, 0, events.size()){ if(i == events.size() || !col(events[i], events[i-1])) { for(int i = l, j = r; i < j; i++, j--){ // positions in int p1 = pts[i].i, p2 = pts[j].i; swap(position[p1], position[p2]); int w1 = pts[i].w, w2 = pts[j].w; modify(i, w2, 0, N); modify(j, w1, 0, N); swap(pts[i], pts[j]); } l = N, r= 0; } if(i == events.size() || !par(events[i], events[i-1])) { best = max(best, getbest()); } auto &e = events[i]; l = min(l, position[e.i]), l = min(l, position[e.j]), r = max(r, position[e.i]), r = max(r, position[e.j]); } /* t = ms(); cout << "Preparing events " << t - t0 << endl; t0 = t; */ /* int best = getbest(); for( auto &pars : blocks) { // cout << "pars size " << pars.size() << endl; for(auto &cols : pars){ //cout << "cols size " << cols.size() << endl; int l = N, r = 0; for(event *e : cols) l = min(l, position[e->i]), l = min(l, position[e->j]), r = max(r, position[e->i]), r = max(r, position[e->j]); // swap [l, r] //cout << "swapping " << l << " " << r << endl; for(int i = l, j = r; i < j; i++, j--){ // positions in int p1 = pts[i].i, p2 = pts[j].i; swap(position[p1], position[p2]); int w1 = pts[i].w, w2 = pts[j].w; modify(i, w2, 0, N); modify(j, w1, 0, N); swap(pts[i], pts[j]); } } best = max(best, getbest()); } */ /* t = ms(); cout << "Swapping " << t - t0 << endl; t0 = t;*/ cout << best << endl; } /* 5 -5 5 -2 2 5 10 1 4 -2 4 -5 4 -2 2 7 */

Compilation message (stderr)

bulldozer.cpp: In function 'int main()':
bulldozer.cpp:10:41: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
 #define FOR(i, l, r) for(int i = (l); i < (r); i++)
                                         ^
bulldozer.cpp:155:5: note: in expansion of macro 'FOR'
     FOR(i, 0, events.size()){
     ^~~
bulldozer.cpp:156:14: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         if(i == events.size() || !col(events[i], events[i-1])) {
            ~~^~~~~~~~~~~~~~~~
bulldozer.cpp:168:14: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         if(i == events.size() || !par(events[i], events[i-1])) {
            ~~^~~~~~~~~~~~~~~~
#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...