제출 #64282

#제출 시각아이디문제언어결과실행 시간메모리
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



*/

컴파일 시 표준 에러 (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...