Submission #738856

#TimeUsernameProblemLanguageResultExecution timeMemory
738856lohachoShortcut (IOI16_shortcut)C++14
97 / 100
2033 ms76892 KiB
#include "shortcut.h"
#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
using namespace std;

long long find_shortcut(int n, std::vector<int> l, std::vector<int> d, int c)
{
    vector<long long> pre(n);
    for(int i = 1; i < n; ++i){
        pre[i] = pre[i - 1] + l[i - 1];
    }

    long long low = 0, high = (long long)1e18, mid;
    int d1 = 0, d2 = 0;
    for(int i = 0; i < n; ++i){
        if(d[i] > d1){
            d2 = d1;
            d1 = d[i];
        }
        else if(d[i] > d2){
            d2 = d[i];
        }
    }
    low = d1 + d2;

    vector<pair<long long, int>> srtp(n), srtm(n);
    for(int i = 0; i < n; ++i){
        srtp[i] = {d[i] + pre[i], i};
        srtm[i] = {pre[i] - d[i], i};
    }
    sort(srtp.begin(), srtp.end());
    sort(srtm.begin(), srtm.end());

    while(low < high){
        mid = low + high >> 1;
        long long xmx = (long long)1e18, ymx = (long long)1e18;
        long long xmn = -(long long)1e18, ymn = -(long long)1e18;

        pair<long long, int> ppd1, pmd1, ppd2, pmd2;
        ppd1 = {-(long long)1e18, -1}, pmd1 = {(long long)1e18, 1};
        ppd2 = {-(long long)1e18, -1}, pmd2 = {(long long)1e18, 1};
        for(int i = n - 1, j = n; i >= 0; --i){
            int nid = srtm[i].second;
            while(j && srtp[j - 1].first > srtm[i].first + mid){
                --j;
                if(srtp[j] > ppd1) ppd2 = ppd1, ppd1 = srtp[j];
                else if(srtp[j] > ppd2) ppd2 = srtp[j];
                if(make_pair(pre[srtp[j].second] - d[srtp[j].second], srtp[j].second) < pmd1) pmd2 = pmd1, pmd1 = make_pair(pre[srtp[j].second] - d[srtp[j].second], srtp[j].second);
                else if(make_pair(pre[srtp[j].second] - d[srtp[j].second], srtp[j].second) < pmd2) pmd2 = make_pair(pre[srtp[j].second] - d[srtp[j].second], srtp[j].second);
            }
            if(pmd1.second != nid) xmn = max(xmn, pre[nid] + d[nid] - pmd1.first - mid + c), ymx = min(ymx, pre[nid] - d[nid] + pmd1.first + mid - c);
            else xmn = max(xmn, pre[nid] + d[nid] - pmd2.first - mid + c), ymx = min(ymx, pre[nid] - d[nid] + pmd2.first + mid - c);
            if(ppd1.second != nid) xmx = min(xmx, pre[nid] - d[nid] - ppd1.first + mid - c), ymn = max(ymn, pre[nid] + d[nid] + ppd1.first - mid + c);
            else xmx = min(xmx, pre[nid] - d[nid] - ppd2.first + mid - c), ymn = max(ymn, pre[nid] + d[nid] + ppd2.first - mid + c);
        }
        // cout << low << ' ' << high << ' ' << mid << endl;
        // cout << xmn << ' ' << xmx << ' ' << ymn << ' ' << ymx << endl;
        int f = 0;
        for(int i = 0, j1 = 1, j2 = n - 1; i < n; ++i){
            while(j1 < n && (pre[i] - pre[j1] > xmx || i == j1)) ++j1;
            while(j2 && (pre[i] + pre[j2 - 1] >= ymn)) --j2;
            int j = max(j1, j2);
            if(j < n && pre[i] - pre[j] >= xmn && pre[i] + pre[j] <= ymx){
                f = 1;

                break;
            }
        }

        if(f){
            high = mid;
        }
        else{
            low = mid + 1;
        }
    }

    return low;
}

Compilation message (stderr)

shortcut.cpp: In function 'long long int find_shortcut(int, std::vector<int>, std::vector<int>, int)':
shortcut.cpp:37:19: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   37 |         mid = low + high >> 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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...