제출 #230064

#제출 시각아이디문제언어결과실행 시간메모리
230064oolimry고대 책들 (IOI17_books)C++14
100 / 100
228 ms26744 KiB
#include "books.h"
#include <bits/stdc++.h> 
using namespace std;
const int inf = 1e9;

static int C[1000005];
static int L[1000000];
static int R[1000000];

void extend(int &l, int &r){
	int LBound = min(L[C[l]], L[C[r]]);
	int RBound = max(R[C[l]], R[C[r]]);
	while(true){
		if(l > LBound){
			l--;
			LBound = min(L[C[l]], LBound);
			RBound = max(R[C[l]], RBound);
		}
		else if(r < RBound){
			r++;
			LBound = min(L[C[r]], LBound);
			RBound = max(R[C[r]], RBound);
		}
		else break;
	}
}

long long minimum_walk(vector<int> p, int S){
	int n = p.size();
	int leftMost = S, rightMost = S;
	
	long long ans = 0;
	
	int cnt = 1;
	for(int i = 0;i < n;i++){
		if(C[i] != 0) continue;
				
		int x = i;
		L[cnt] = i;
		while(true){
			C[x] = cnt;
			R[cnt] = max(R[cnt], x);
			
			ans += abs(x - p[x]); ///essential moves
			
			x = p[x];
			if(x == i) break;
		}
		
		if(i != p[i]){
			leftMost = min(L[cnt], leftMost);
			rightMost = max(R[cnt], rightMost);
		}
		cnt++;
	}
	
	int l = S, r = S;
	while(true){
		if(l == leftMost && r == rightMost) break;
		extend(l,r);
		bool hasExtension = false;
		
		int newL = n, newR = 0;
		///try to go left first
		int LCost = 0;
		int ll = l, rr = r; ///temporary, try first
		while(true){
			if(ll <= leftMost) break;
			ll--; LCost += 2;
			extend(ll, rr);
			if(rr > r){
				hasExtension = true;
				break;
			}
		}
		newL = min(ll, newL);
		newR = max(rr, newR);
		
		///then try to go right
		int RCost = 0;
		ll = l, rr = r; ///temporary, try first
		while(true){
			if(rr >= rightMost) break;
			rr++; RCost += 2;
			extend(ll, rr);
			if(ll < l){
				hasExtension = true;
				break;
			}
		}
		newL = min(ll, newL);
		newR = max(rr, newR);
		
		if(hasExtension) ans += min(LCost, RCost);
		else ans += LCost + RCost;
		
		l = newL; r = newR;
		
		if(l == leftMost && r == rightMost) break;
	}
		
	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...