This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |