Submission #1105052

#TimeUsernameProblemLanguageResultExecution timeMemory
1105052alexander707070Ancient Books (IOI17_books)C++14
50 / 100
116 ms29440 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; dp[l][r]=2*n; 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)+2); } if(r<n){ 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)+2); } 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)-2; 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...