제출 #1186488

#제출 시각아이디문제언어결과실행 시간메모리
1186488Hanksburger밀림 점프 (APIO21_jumps)C++17
100 / 100
1411 ms55224 KiB
#include "jumps.h" #include <bits/stdc++.h> using namespace std; int h[200005], l[200005], r[200005], good[20][200005], bad[20][200005], n; struct node { node *lc, *rc; int l, r; pair<int, int> val; node(int l, int r) : lc(0), rc(0), l(l), r(r), val({0, 0}) {} } *root; void build(node *i) { if (i->l==i->r) { i->val={h[i->l], i->l}; return; } int mid=(i->l+i->r)/2; i->lc=new node(i->l, mid); i->rc=new node(mid+1, i->r); build(i->lc); build(i->rc); i->val=max(i->lc->val, i->rc->val); } pair<int, int> query(node *i, int ql, int qr) { if (ql<=i->l && i->r<=qr) return i->val; int mid=(i->l+i->r)/2; pair<int, int> ans={0, 0}; if (i->l<=qr && ql<=mid) ans=max(ans, query(i->lc, ql, qr)); if (mid<qr && ql<=i->r) ans=max(ans, query(i->rc, ql, qr)); return ans; } void init(int N, vector<int> H) { n=N; h[0]=h[n+1]=1e9; for (int i=1; i<=n; i++) h[i]=H[i-1]; stack<int> q; q.push(0); for (int i=1; i<=n; i++) { while (h[q.top()]<h[i]) q.pop(); l[i]=q.top(); q.push(i); } while (q.size()) q.pop(); q.push(n+1); for (int i=n; i; i--) { while (h[q.top()]<h[i]) q.pop(); r[i]=q.top(); q.push(i); } good[0][n+1]=bad[0][n+1]=n+1; for (int i=1; i<=n; i++) { good[0][i]=h[l[i]]>h[r[i]]?l[i]:r[i]; bad[0][i]=h[l[i]]<h[r[i]]?l[i]:r[i]; } for (int i=1; i<20; i++) { for (int j=0; j<=n+1; j++) { good[i][j]=good[i-1][good[i-1][j]]; bad[i][j]=bad[i-1][bad[i-1][j]]; } } root=new node(1, n); build(root); } int calc(int u, int v) { int ans=0; for (int i=19; i>=0; i--) { if (h[good[i][u]]<=h[v]) { u=good[i][u]; ans+=1<<i; } } for (int i=19; i>=0; i--) { if (h[bad[i][u]]<=h[v]) { u=bad[i][u]; ans+=1<<i; } } if (u==v) return ans; return -1; } int minimum_jumps(int a, int b, int c, int d) { a++, b++, c++, d++; pair<int, int> ans1=query(root, c, d); int l=a, r=b+1; while (l<r) { int mid=(l+r)/2; pair<int, int> ans2=query(root, mid, b); if (ans2.first>ans1.first) l=mid+1; else r=mid; } if (l==b+1) return -1; pair<int, int> ans2=query(root, l, b); pair<int, int> ans4=(b+2<=c)?query(root, b+1, c-1):make_pair(0, 0); int ll=c, rr=d; while (ll<rr) { int mid=(ll+rr)/2; pair<int, int> ans3=query(root, c, mid); if (max(ans2.first, ans4.first)<ans3.first) rr=mid; else ll=mid+1; } pair<int, int> ans3=query(root, c, ll); int res=calc(ans2.second, ans3.second); if (l==a) { if (ans2.first>ans4.first) return 1; int ans=0, u=ans2.second; for (int i=19; i>=0; i--) { if (h[good[i][u]]<ans4.first) { u=good[i][u]; ans+=1<<i; } } u=good[0][u]; if (h[u]<ans1.first) { ans+=2; if (res==-1) res=ans; else res=min(res, ans); } } return res; }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...