Submission #496513

#TimeUsernameProblemLanguageResultExecution timeMemory
496513PedroBigManAncient Books (IOI17_books)C++14
12 / 100
18 ms27724 KiB
/* Author of all code: Pedro BIGMAN Dias Last edit: 15/02/2021 */ #pragma GCC optimization ("O3") #pragma GCC optimization ("unroll-loops") #pragma GCC optimize("Ofast") #include <iostream> #include <vector> #include <cmath> #include <algorithm> #include <string> #include <map> #include <unordered_map> #include <set> #include <unordered_set> #include <queue> #include <deque> #include <list> #include <iomanip> #include <stdlib.h> #include <time.h> #include <cstring> #include "books.h" using namespace std; typedef long long int ll; typedef unsigned long long int ull; typedef long double ld; #define REP(i,a,b) for(ll i=(ll) a; i<(ll) b; i++) #define pb push_back #define mp make_pair #define pl pair<ll,ll> #define ff first #define ss second #define whole(x) x.begin(),x.end() #define DEBUG(i) cout<<"Pedro Is The Master "<<i<<endl #define INF 500000000LL #define EPS 0.00000001 #define pi 3.14159 #define VV(vvvv,NNNN,xxxx); REP(i,0,NNNN) {vvvv.pb(xxxx);} ll mod=1000000007LL; template<class A=ll> void Out(vector<A> a) {REP(i,0,a.size()) {cout<<a[i]<<" ";} cout<<endl;} template<class A=ll> void In(vector<A> &a, ll N) {A cur; REP(i,0,N) {cin>>cur; a.pb(cur);}} class ST { public: ll N; class SV //seg value { public: ll a; SV() {a=0LL;} SV(ll x) {a=x;} SV operator & (SV X) {SV ANS(a+X.a); return ANS;} }; class LV //lazy value { public: ll a; LV() {a=0LL;} LV(ll x) {a=x;} LV operator & (LV X) {LV ANS(a+X.a); return ANS;} }; SV upval(ll c) //how lazy values modify a seg value inside a node, c=current node { SV X(p[c].a+(range[c].ss-range[c].ff+1)*lazy[c].a); return X; } SV neuts; LV neutl; vector<SV> p; vector<LV> lazy; vector<pl> range; ST() {N=0LL;} ST(vector<ll> arr) { N = (ll) 1<<(ll) ceil(log2(arr.size())); REP(i,0,2*N) {range.pb(mp(0LL,0LL));} REP(i,0,N) {p.pb(neuts);} REP(i,0,arr.size()) {SV X(arr[i]); p.pb(X); range[i+N]=mp(i,i);} REP(i,arr.size(),N) {p.pb(neuts); range[i+N]=mp(i,i);} ll cur = N-1; while(cur>0) { p[cur]=p[2*cur]&p[2*cur+1]; range[cur]=mp(range[2*cur].ff,range[2*cur+1].ss); cur--; } REP(i,0,2*N) {lazy.pb(neutl);} } void prop(ll c) //how lazy values propagate { lazy[2*c]=lazy[c]&lazy[2*c]; lazy[2*c+1]=lazy[c]&lazy[2*c+1]; lazy[c]=neutl; } SV query(ll a,ll b, ll c=1LL) //range [a,b], current node. initially: query(a,b) { ll x=range[c].ff; ll y=range[c].ss; if(y<a || x>b) {return neuts;} if(x>=a && y<=b) {return upval(c);} prop(c); p[c]=upval(2*c)&upval(2*c+1); SV ans = query(a,b,2*c)&query(a,b,2*c+1); return ans; } void update(LV s, ll a, ll b, ll c=1LL) //update LV, range [a,b], current node, current range. initially: update(s,a,b) { ll x=range[c].ff; ll y=range[c].ss; if(y<a || x>b) {return ;} if(x>=a && y<=b) { lazy[c]=s&lazy[c]; return; } prop(c); update(s,a,b,2*c); update(s,a,b,2*c+1); p[c]=upval(2*c)&upval(2*c+1); } }; vector<vector<ll> > CycleDecomp(vector<int> p) //cycle decomposition of permutation { ll N = p.size(); vector<vector<ll> > ans; vector<ll> cur; vector<bool> visited; REP(i,0,N) {visited.pb(false);} ll node; REP(i,0,N) { if(visited[i]) {continue;} node=i; cur.pb(node); node=p[node]; while(node!=i) { cur.pb(node); node=p[node]; } REP(i,0,cur.size()) {visited[cur[i]]=true;} ans.pb(cur); cur.clear(); } return ans; } class WDiGraph { public: ll N; vector<vector<pl> > adj; vector<bool> visited; WDiGraph(vector<vector<pl> > ad) { adj=ad; N=adj.size(); REP(i,0,N) {visited.pb(false);} } vector<ll> BFS(ll s) { vector<ll> distance; REP(i,0,N) {distance.pb(INF);} REP(i,0,N) {visited[i]=false;} distance[s]=0; visited[s]=true; deque<ll> d; d.pb(s); ll cur; while(!d.empty()) { cur=d.front(); d.pop_front(); REP(i,0,adj[cur].size()) { if(!visited[adj[cur][i].ff]) { visited[adj[cur][i].ff]=true; d.pb(adj[cur][i].ff); distance[adj[cur][i].ff]=distance[cur]+1; } } } return distance; } }; ll minimum_walk(vector<int> p, int s) { ll N = p.size(); vector<vector<ll> > C = CycleDecomp(p); vector<pl> range; REP(i,0,C.size()) {range.pb({*min_element(whole(C[i])),*max_element(whole(C[i]))});} vector<ll> xx; VV(xx,N-1,0); ST S(xx); REP(i,0,range.size()) {if(range[i].ff==range[i].ss) {continue;} S.update(1,range[i].ff,range[i].ss-1);} vector<bool> in; VV(in,N-1,false); REP(i,0,N-1) {if(S.query(i,i).a>0) {in[i]=true;}} ll l=0,r=N-2; while(l<s && !in[l]) {l++;} while(r>=s && !in[r]) {r--;} ll ans=0LL; REP(i,l,r+1) {if(!in[i]) {ans+=2LL;}} REP(i,0,N) {ans+=((ll) (abs(p[i]-i)));} ll T=s; while(T<N-1 && in[T]) {T++;} ll SS; bool ok=false; REP(i,0,C.size()) {REP(j,0,C[i].size()) {if(C[i][j]==T) {T=i;ok=true;break;}} if(ok) {break;}} ok=false; REP(i,0,C.size()) {REP(j,0,C[i].size()) {if(C[i][j]==s) {SS=i;ok=true;break;}} if(ok) {break;}} REP(i,0,C.size()) {sort(whole(C[i]));} vector<vector<pl> > adj; VV(adj,C.size(),{}); vector<ll>::iterator it; REP(i,0,C.size()) { REP(j,0,C.size()) { if(i==j) {continue;} it = lower_bound(whole(C[j]),range[i].ff); if(it!=C[j].end() && (*it)<=range[i].ss) {adj[i].pb({j,0LL}); continue;} ll dist=INF; if(it!=C[j].begin()) {it--; dist=min(dist,range[i].ff-*it);} it=upper_bound(whole(C[j]),range[i].ss); if(it!=C[j].end()) {dist=min(dist,*it - range[i].ss);} adj[i].pb({j,dist}); } } WDiGraph G(adj); vector<ll> d = G.BFS(SS); ans+=2LL*d[T]; return ans; }

Compilation message (stderr)

books.cpp:5: warning: ignoring '#pragma GCC optimization' [-Wunknown-pragmas]
    5 | #pragma GCC optimization ("O3")
      | 
books.cpp:6: warning: ignoring '#pragma GCC optimization' [-Wunknown-pragmas]
    6 | #pragma GCC optimization ("unroll-loops")
      | 
books.cpp: In function 'll minimum_walk(std::vector<int>, int)':
books.cpp:232:42: warning: 'SS' may be used uninitialized in this function [-Wmaybe-uninitialized]
  232 |  WDiGraph G(adj); vector<ll> d = G.BFS(SS); ans+=2LL*d[T];
      |                                          ^
#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...