Submission #71103

#TimeUsernameProblemLanguageResultExecution timeMemory
71103gnoorAncient Books (IOI17_books)C++17
70 / 100
379 ms37492 KiB
#include "books.h" #include <vector> #include <algorithm> #include <cmath> #include <cassert> #include <cstdio> #include <cstring> using namespace std; bool visit[1000100]; long long dis[1000100]; vector<pair<int,int>> uni(vector<pair<int,int>> &tbl) { sort(tbl.begin(),tbl.end(),[](const pair<int,int> &a,const pair<int,int> &b) { if (a.second!=b.second) return a.second<b.second; return a.first<b.first; }); vector<pair<int,int>> re; for (int i=0;i<(int)tbl.size();i++) { int curl=tbl[i].first; while (!re.empty()&&tbl[i].first<=re.back().second) { curl=min(curl,re.back().first); re.pop_back(); } re.push_back({curl,tbl[i].second}); } return re; } struct seg { int cl,cr,pl,pr; }; vector<seg> rem(vector<seg> &tbl,vector<seg> &out) { sort(tbl.begin(),tbl.end(),[](const seg &a, const seg &b) { if (a.cr!=b.cr) return a.cr<b.cr; return a.cl>b.cl; }); vector<seg> res; for (int i=0;i<(int)tbl.size();i++) { while (!res.empty()&&tbl[i].cl<=res.back().cl) { out.push_back(res.back()); res.pop_back(); } res.push_back(tbl[i]); } return res; } long long minimum_walk(vector<int> p, int s) { int n=(int)p.size(); vector<pair<int,int>> coord; vector<seg> over; vector<seg> nonover; long long ans=0; for (int i=0;i<n;i++) { if (visit[i]) continue; visit[i]=true; int mn=i; int mx=i; int cl=-1e9; int cr=1e9; if (i<=s) cl=max(cl,i); if (i>=s) cr=min(cr,i); int cur=p[i]; ans+=abs(p[i]-i); while (cur!=i) { visit[cur]=true; mx=max(mx,cur); mn=min(mn,cur); if (cur<=s) cl=max(cl,cur); if (cur>=s) cr=min(cr,cur); ans+=abs(p[cur]-cur); cur=p[cur]; } if (mn==mx) continue; coord.push_back({mn,mx}); if (mn>=s||mx<=s) nonover.push_back(seg{cl,cr,mn,mx}); else over.push_back(seg{cl,cr,mn,mx}); } coord.push_back({s,s}); auto re=uni(coord); for (int i=1;i<(int)re.size();i++) { ans+=(re[i].first-re[i-1].second)*2; } if (over.empty()) { return ans; } //------------------------------------------- vector<seg> byl=nonover; vector<seg> byr=nonover; sort(byr.begin(),byr.end(),[](const seg &a, const seg &b) { return a.cr<b.cr; }); while (!byr.empty()&&byr.back().cr==1e9) byr.pop_back(); sort(byl.begin(),byl.end(),[](const seg &a, const seg &b) { return a.cl>b.cl; }); while (!byl.empty()&&byl.back().cl==-1e9) byl.pop_back(); //----------------------- while (!over.empty()) { vector<seg> tmp; auto res=rem(over,tmp); over=tmp; int tgtl=-1e9; int tgtr=1e9; for (auto &i:res) { tgtl=max(tgtl,i.cl); tgtr=min(tgtr,i.cr); } int stl=s; int str=s; for (auto &i:over) { stl=min(stl,i.pl); str=max(str,i.pr); } int curr=str; long long addr=0; for (auto &i:byr) { if (curr>=tgtr) break; if (i.cr>=tgtr) break; if (i.cr>curr) { addr+=(i.cr-curr)*2ll; } curr=max(curr,i.pr); } if (tgtr>curr) addr+=(tgtr-curr)*2ll; int curl=stl; long long addl=0; for (auto &i:byl) { if (curl<=tgtl) break; if (i.cl<=tgtl) break; if (i.cl<curl) { addl+=(curl-i.cl)*2ll; } curl=min(curl,i.pl); } if (tgtl<curl) addl+=(curl-tgtl)*2ll; ans+=min(addr,addl); } return ans; }
#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...