# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
1279127 | MMihalev | 고대 책들 (IOI17_books) | C++20 | 0 ms | 0 KiB |
#include<iostream>
#include<vector>
//#include "books.h"
using namespace std;
const int MAX_N=1e6+6;
int col[MAX_N];
int cols;
int a[MAX_N];
int l[MAX_N];
int r[MAX_N];
int n;
long long ans;
long long minimum_walk(std::vector<int> p, int s)
{
n=p.size();
s++;
for(int i=1;i<=n;i++)
{
l[i]=1e9;
r[i]=-1;
a[i]=p[i-1]+1;
}
///init stuff
for(int i=1;i<=n;i++)
{
ans+=abs(i-a[i]);
if(col[i]==0)
{
if(i!=s && i==a[i])continue;
cols++;
int pos=i;
while(col[pos]==0)
{
l[cols]=min(l[cols],pos);
r[cols]=max(r[cols],pos);
col[pos]=cols;
pos=a[pos];
}
}
}
int tmpstart=-1,tmpend=-1;
int compstart=-1,compend=-1;
vector<int>sep;
bool has=0;
int active=0;
int e=n;
while(col[e]==0)e--;
for(int i=1;i<=e;i++)
{
if(has && active==0)
{
sep.push_back(i-1);
}
int curcol=col[i];
if(l[curcol]==i)
{
if(active==0)tmpstart=i;
has=1;
active++;
}
if(r[curcol]==i)
{
if(active==1)
{
tmpend=i;
}
active--;
}
if(tmpstart<=s && s<=tmpend)
{
compstart=tmpstart;
compend=tmpend;
}
}
int ll=s,rr=s;
int oldl=ll+1,oldr=rr-1;
while(1)
{
if(ll==compstart && rr==compend)break;
int nl=ll,nr=rr;
for(int i=ll;i<oldl;i++)
{
nl=min(nl,l[col[i]]);
nr=max(nr,r[col[i]]);
}
for(int i=oldr+1;i<=rr;i++)
{
nl=min(nl,l[col[i]]);
nr=max(nr,r[col[i]]);
}
if(nl!=ll or nr!=rr)
{
oldl=ll;
oldr=rr;
ll=nl;
rr=nr;
}
else
{
int distr=0,tmpr=rr;
while(1)
{
distr++;
tmpr++;
while(col[tmpr]==0)
{
distr++;
tmpr++;
}
bool foundnew=0;
/*if(col[tmpl]!=0)
{
int newcomponentl,newcomponentr;
tie(newcomponentl,newcomponentr)=findcomponent(tmpl);
if(newcomponentr>rr)
{
ll=newcomponentl;
rr=newcomponentr;
foundnew=1;
}
else
{
ll=newcomponentl;
}
}
else*/
int newcomponentl,newcomponentr;
tie(newcomponentl,newcomponentr)=findcomponent(tmpr);
if(newcomponentl<ll)
{
foundnew=1;
}
else
{
tmpr=newcomponentr;
}
if(foundnew)
{
}
}
}
}
if(sep.size()==0)return ans;
///cycle stuff
for(int i=sep.size()-1;i>=0;i--)
{
if(sep[i]>=s)ans+=2;
}
///right part
for(int i=0;i<sep.size();i++)
{
if(sep[i]<s)ans+=2;
}
///left part
return ans;
}