제출 #591803

#제출 시각아이디문제언어결과실행 시간메모리
591803FatihSolakShortcut (IOI16_shortcut)C++17
97 / 100
2057 ms98164 KiB
#include "shortcut.h"
#include <bits/stdc++.h>
#define N 1000005
using namespace std;
long long p[N];
long long d[N];
int n,nwedge;
vector<pair<long long,int>> a;
vector<pair<long long,pair<int,int>>> b;
long long val1[N],val2[N];
bool ck(long long k){
    for(int i = 0;i<n;i++){
        val1[i] = -1e18;
        val2[i] = 1e18;
    }
    int pt = n;
    for(int i = 0;i<n;i++){
        while(pt && b[pt-1].first + a[i].first > k){
            pt--;
        }
        if(pt != n){
            val1[(b[pt].second.first == a[i].second?b[pt].second.second:b[pt].second.first)] = max(val1[(b[pt].second.first == a[i].second?b[pt].second.second:b[pt].second.first)],p[a[i].second] + d[a[i].second]);
            val2[(b[pt].second.first == a[i].second?b[pt].second.second:b[pt].second.first)] = min(val2[(b[pt].second.first == a[i].second?b[pt].second.second:b[pt].second.first)],p[a[i].second] - d[a[i].second]);
        }
    }
    long long xl = -1e18, xr = 1e18;
    long long yl = -1e18, yr = 1e18;

    stack<int> st;
    for(int i = 0;i<n;i++){
        while(st.size() && p[st.top()] + d[st.top()] <= p[i] + d[i]){
            val1[i] = max(val1[i],val1[st.top()]);
            val2[i] = min(val2[i],val2[st.top()]);
            st.pop();
        }
        xl = max(xl,+ p[i]  - (k - d[i] - nwedge) + val1[i]);
        xr = min(xr,+ p[i]  + (k - d[i] - nwedge) + val2[i]);
        yl = max(yl,- p[i]  - (k - d[i] - nwedge) + val1[i]);
        yr = min(yr,- p[i]  + (k - d[i] - nwedge) + val2[i]);
        st.push(i);
    }
    if(xl > xr || yl > yr)return 0;
    int pt1 = n,pt2 = n-1;
    int pt3 = -1,pt4 = 0;
    for(int i = 0;i<n;i++){
        while(pt1 && p[pt1-1] + p[i] >= xl){
            pt1--;
        }
        while(pt2 &&  p[pt2] + p[i] > xr){
            pt2--;
        }

        while(pt3 + 1 != n && -p[pt3+1] + p[i] >= yl){
            pt3++;
        }
        while(pt4 != n &&  -p[pt4] + p[i] > yr){
            pt4++;
        }

        int l1 = pt1,r1 = pt2;
        int l2 = pt4,r2 = pt3;

        if(r1 < l1 || r2 < l2)continue;
        if(r1 < l2 || r2 < l1)continue;
        
        return 1;
    }
    return 0;
}
long long find_shortcut(int n_, vector<int> l_, vector<int> d_, int nwedge_)
{
    n = n_;
    nwedge = nwedge_;
    for(int i = 1;i<n;i++){
        p[i] = p[i-1] + l_[i-1];
    }
    for(int i = 0;i<n;i++){
        d[i] = d_[i];
    }
    for(int i = 0;i<n;i++){
        a.push_back({-p[i] + d[i],i});
    }
    for(int i = 0;i<n;i++){
        b.push_back({p[i] + d[i],{i,n}});
    }
    sort(a.begin(),a.end());
    sort(b.begin(),b.end());

    for(int i = b.size()-2;i>=0;i--){
        if(min(b[i].second.first,b[i+1].second.first) == b[i].second.first){
            b[i].second.second = min(b[i].second.second,b[i+1].second.first);
        }
        else b[i].second.second = min(b[i].second.first,b[i+1].second.second);
        b[i].second.first = min(b[i].second.first,b[i+1].second.first);
    }
    long long l = 0, r = 1e16;
    while(l < r){
        long long m = (l + r)/2;
        if(ck(m)){
            r = m;
        }
        else l = m+1;
    }
    return l;
}
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...