제출 #282583

#제출 시각아이디문제언어결과실행 시간메모리
282583Noam13고대 책들 (IOI17_books)C++14
100 / 100
943 ms148392 KiB
#include "books.h"
#include <bits/stdc++.h>
#define vi vector<int>
#define vvi vector<vi>
#define vb vector<bool>
#define vvb vector<vb>
#define ii pair<int, int>
#define x first
#define y second
#define vii vector<ii>
#define pb push_back
#define all(x) x.begin(), x.end()
#define loop(i,s,e) for(int i=s;i<e;++i)
#define chkmax(a,b) a = max(a,b)
#define chkmin(a,b) a = min(a,b)
using namespace std;
const int INF = 1e9;
typedef long long ll;

struct DSU{
	int n;
	vi p, sz;
	DSU(int n):n(n), p(n,-1), sz(n,1){}
	int find(int c){
		if (p[c]==-1) return c;
		return p[c] = find(p[c]);
	}
	void uni(int a, int b){
		a = find(a), b = find(b);
		if (a==b) return  ;
		if (sz[a]>sz[b]) swap(a,b);
		p[a] = b;
		sz[b] += sz[a];
	}
};
ll minimum_walk(vi p, int s) {
	ll ans = 0;
	int n = p.size();
	vb check(n,0);
	int needl = s, needr = s;
	vi v1(n), v2(n);
	loop(i,0,n) if(!check[i]){
		vi vec;
		int mn = i, mx = i;
		for(int cur = i;!check[cur]; cur = p[cur]){
			check[cur] = 1;
			ans+=abs(cur-p[cur]);
			vec.pb(cur);
			chkmin(mn, cur); chkmax(mx, cur);
		}
		if (vec.size()>1) chkmax(needr, mx), chkmin(needl, mn);
		for(auto x:vec) v2[x] = mx, v1[x] = mn;
	}
	int l = s, r = s, ml=s, mr=s;
	while(l>=ml || r<=mr){
		if (l>=ml){
			chkmax(mr, v2[l]);
			chkmin(ml, v1[l]);
			l--;
		}
		else{
			chkmax(mr, v2[r]);
			chkmin(ml, v1[r]);
			r++;
		}
	}
	vi right(1,l+1), left(1,r-1);
	vi comp(n,0); int cnt = 0;
	while(r<n){
		if (r>mr) right.pb(n), mr++, cnt++;
		comp[r] = cnt;
		chkmax(mr, v2[r]); 
		chkmin(right.back(), v1[r]);
		r++;
	}
	cnt = 0;
	while(l>=0){
		if (l<ml) left.pb(-1), ml--, cnt++;
		comp[l] = cnt;
		chkmin(ml, v1[l]); 
		chkmax(left.back(), v2[l]);
		l--;
	}
	int a = left.size(), b = right.size();
	for(int &x:left) x = comp[x] + (x>s?a:0);
	for(int &x:right) x = comp[x] + (x>s?a:0);
	needl = comp[needl], needr = comp[needr];
	DSU dsu(a+b);
	dsu.uni(0,a); //same one
	loop(i,0,a) dsu.uni(i, left[i]);
	loop(i,0,b) dsu.uni(i+a, right[i]);
	map<int, int> conv; int tmp=0;
	loop(i,0,a+b) if(dsu.p[i]==-1) conv[i]=tmp++;
	vvi g(tmp);
	auto get = [&](int i){
		return conv[dsu.find(i)];
	};
	loop(i,0,a-1){
		int aa = get(i), bb = get(i+1);
		if (aa!=bb) g[aa].pb(bb);
	}
	loop(i,0,b-1){
		int aa = get(i+a), bb = get(i+a+1);
		if (aa!=bb) g[aa].pb(bb);
	}	
	vi vals(tmp);
	loop(i,0,a) vals[get(i)]|=1; 
	loop(i,0,b) vals[get(i+a)]|=2;
	//one that has 3 is both
	needl = get(needl), needr = get(needr+a); //updating targets
	queue<int> q; q.push(get(0));
	vi dist(tmp,-1); dist[get(0)] = 0;
	int has = 0, lasty = 0, lasth=0;
	//cout<<"AB: "<<a<<" "<<b<<" "<<ans<<endl;
	while(q.size()){
		int cur = q.front(); q.pop();
		if (vals[cur]==3) lasty = dist[cur];
		if (cur==needl) ans+=2*dist[cur], has|=1;
		if (cur==needr) ans+=2*dist[cur], has|=2;
		//cout<<"CUR: "<<cur<<" "<<dist[cur]<<endl;
		if (has!=0 && lasth==0){
			ans-=2*lasty;
		}
		if (has==3) break;
		lasth = has;
		for(auto nei:g[cur]) if(dist[nei]==-1){
			dist[nei]=dist[cur]+1;
			q.push(nei);
		}
	}
	return ans;
}
/*
clear
g++ books.cpp grader.cpp -o a ; ./a
4 0
0 2 3 1

11 2
10 5 2 4 3 8 7 6 1 9 0

4 1 3 2 7 6 5 0
*/
#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...