제출 #1363777

#제출 시각아이디문제언어결과실행 시간메모리
1363777AvianshText editor (CEOI24_editor)C++20
56 / 100
4119 ms760480 KiB
#include <bits/stdc++.h>

using namespace std;

#define int long long

const int inf = 2e18;

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n;
    cin >> n;
    int sl,sc;
    cin >> sl >> sc;
    sl--;
    sc--;
    int el,ec;
    cin >> el >> ec;
    el--;
    ec--;
    int arr[n];
    for(int &i : arr){
        cin >> i;
        ++i;
    }
    set<array<int,2>>pts[n];
    priority_queue<array<int,3>,vector<array<int,3>>,greater<array<int,3>>>pq;
    pq.push({0,sl,sc});
    auto dist = [&] (int l, int c){
        if(pts[l].size()==0)
            return inf;
        auto it = pts[l].lower_bound({c,-1});
        int ans = inf;
        if(it!=pts[l].end()){
            ans=min(ans,abs((*it)[0]-c)+(*it)[1]);
        }
        if(it!=pts[l].begin()){
            it--;
            ans=min(ans,abs((*it)[0]-c)+(*it)[1]);
        }
        return ans;
    };
    while(!pq.empty()){
        array<int,3>a = pq.top();
        pq.pop();
        if(a[1]<0||a[1]>=n){
            continue;
        }
        if(a[2]>=arr[a[1]]){
            a[2]=arr[a[1]]-1;
        }
        if(dist(a[1],a[2])<=a[0]){
            continue;
        }
        auto it = pts[a[1]].lower_bound({a[2],-1});
        while(it!=pts[a[1]].end()){
            array<int,2>pt = *it;
            if(abs(pt[0]-a[2])+a[0]<=pt[1]){
                pts[a[1]].erase(it);
            }
            else{
                break;
            }
            it = pts[a[1]].lower_bound({a[2],-1});
        }
        if(pts[a[1]].size()){
            it = pts[a[1]].upper_bound({a[2],inf});
            while(pts[a[1]].size()&&it!=pts[a[1]].begin()){
                --it;
                array<int,2>pt = *it;
                if(abs(pt[0]-a[2])+a[0]<=pt[1]){
                    pts[a[1]].erase(it);
                }
                else{
                    break;
                }
                it = pts[a[1]].upper_bound({a[2],inf});
            }
        }
        //pruned front and back
        //now see if actually pushable
        if(dist(a[1],a[2])<=a[0]){
            //not pushable already handled
            //also already checked
            assert(0);
        }
        else{
            //pushable
            pts[a[1]].insert({a[2],a[0]});
            pq.push({a[0]+1,a[1]-1,a[2]});
            pq.push({a[0]+1,a[1]+1,a[2]});
            //check if corners are new now

            ///left
            if((*pts[a[1]].begin())[0]==0&&a[2]!=0){
                //left still exist so no change here
            }
            else{
                //left no exist or this one was leftmost so now put new here
                pts[a[1]].insert({0,dist(a[1],0)});
                pq.push({dist(a[1],0)+1,a[1]-1,0});
                pq.push({dist(a[1],0)+1,a[1]+1,0});
                if(a[1]){
                    pq.push({dist(a[1],0)+1,a[1]-1,arr[a[1]-1]-1});
                }
            }
            ///right
            if((*--pts[a[1]].end())[0]==arr[a[1]]-1&&a[2]!=arr[a[1]]-1){
                //right still exist so no change here
            }
            else{
                //right no exist or this one was leftmost so now put new here
                pts[a[1]].insert({arr[a[1]]-1,dist(a[1],arr[a[1]]-1)});
                pq.push({dist(a[1],arr[a[1]]-1)+1,a[1]-1,arr[a[1]]-1});
                pq.push({dist(a[1],arr[a[1]]-1)+1,a[1]+1,arr[a[1]]-1});
                pq.push({dist(a[1],arr[a[1]]-1)+1,a[1]+1,0});
            }
        }
    }
    cout << dist(el,ec);
    return 0;
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…