Submission #1105029

#TimeUsernameProblemLanguageResultExecution timeMemory
1105029alexander707070Ancient Books (IOI17_books)C++14
50 / 100
122 ms32588 KiB
#include<bits/stdc++.h>
#define MAXN 1000007
using namespace std;

int n,s,p[MAXN],fr,last,mins,maxs,pref[MAXN],curr;
bool li[MAXN];
long long ans;

int k,cycle[MAXN];
pair<int,int> where[MAXN];

void dfs(int x){
	li[x]=true;
	cycle[x]=k;

	ans+=abs(x-p[x]);
	mins=min(mins,x);
	maxs=max(maxs,x);

	if(!li[p[x]])dfs(p[x]);
}

int dp[1007][1007];
bool vis[1007][1007];

int ff(int l,int r){
	if(l==1 and r==n)return 0;
	
	if(vis[l][r])return dp[l][r];
	vis[l][r]=true;

	if(l>1){
		int from=l-1,to=r,ll=l-1,rr=r+1;
		while(ll>=from or rr<=to){
			while(ll>=from){
				from=min(from,where[cycle[ll]].first);
				to=max(to,where[cycle[ll]].second);
				ll--;
			}

			while(rr<=to){
				from=min(from,where[cycle[rr]].first);
				to=max(to,where[cycle[rr]].second);
				rr++;
			}
		}

		dp[l][r]=min(dp[l][r],ff(from,to)+1);
	}

	if(l>1){
		int from=l,to=r+1,ll=l-1,rr=r+1;
		while(ll>=from or rr<=to){
			while(ll>=from){
				from=min(from,where[cycle[ll]].first);
				to=max(to,where[cycle[ll]].second);
				ll--;
			}

			while(rr<=to){
				from=min(from,where[cycle[rr]].first);
				to=max(to,where[cycle[rr]].second);
				rr++;
			}
		}

		dp[l][r]=min(dp[l][r],ff(from,to)+1);
	}

	return dp[l][r];
}

long long minimum_walk(vector<int> P, int S){
	n=int(P.size()); s=S+1;

	for(int i=1;i<=n;i++){
		p[i]=P[i-1]+1;
		li[i]=false; pref[i]=0;
	}
	last=0; fr=n+1; k=0; ans=0;

	for(int i=1;i<=n;i++){
		if(!li[i]){
			if(p[i]!=i)last=i;
			dfs(i);
		}
	}

	for(int i=1;i<=n;i++)li[i]=false;

	for(int i=n;i>=1;i--){
		if(!li[i]){
			k++;
			if(p[i]!=i)fr=i;

			mins=n; maxs=1;
			dfs(i);

			where[k]={mins,maxs};
			pref[mins]++; pref[maxs]--;
		}
	}
	ans/=2;

	/// more steps inside initial cycle

	if(s!=1)ans+=ff(s,s);
	else{
		for(int i=1;i<=n-1;i++){
			curr+=pref[i];
			if(i<s)continue;
	
			if(curr==0 and last>i)ans+=2;
		}
	
		curr=0;
		for(int i=n;i>=2;i--){
			curr+=pref[i];
			if(i>s)continue;
	
			if(curr==0 and fr<i)ans+=2;
		}
	}
	
	return ans;
}

/*int main(){

	vector<int> perm;
	for(int i=0;i<10;i++){
		perm.push_back(i);
	}

	while(true){
		random_shuffle(perm.begin(),perm.end());
		for(int i=0;i<10;i++){
			cout<<perm[i]<<" ";
		}
		cout<<"\n";

		int z=rand()%10;

		cout<<z<<"\n";
		minimum_walk(perm,z);
	}

	return 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...