This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
#include <cstdio>
#include <cassert>
using namespace std;
#define FOR(i,n) for (int i=1;i<=n;i++)
#define REP(i,a,b) for (int i=a;i<=b;i++)
#define pb push_back
#define fi first
#define se second
#define pi pair<int,int>
#define mp make_pair
typedef long long ll;
const int inf=0x3f3f3f3f;
const ll linf=1e18;
const int N=100000+10;
const double eps=1e-5;
const int mo=1e9+7;
int n,m,m2;
ll x[N],h[N];
struct bridge {
int l,r;
ll y;
} e[N];
bool cmp(bridge a,bridge b) {
if (a.y==b.y&&a.l!=b.l) return a.l<b.l;
if (a.y==b.y&&a.l==b.l) return a.r<b.r;
return a.y<b.y;
}
bool cmp2(int a,int b) {
if (e[a].y==e[b].y&&e[a].l!=e[b].l) return e[a].l<e[b].l;
if (e[a].y==e[b].y&&e[a].r!=e[b].r) return e[a].r<e[b].r;
return e[a].y>e[b].y;
}
int s,g;
vector<int> c,d;
int ch,ct,dh,dt;
vector<int> lb[N],rb[N];
ll rec[N];
int to[N];
ll slt[3][4*N],srt[3][4*N],glt[3][4*N],grt[3][4*N];
struct state {
int maxh,l,r,lstop,rstop;
} su,gu;
bool turn;// 0表示轮到sr向右移动,1表示轮到gr向右移动
int slp[4*N],srp[4*N],glp[4*N],grp[4*N];
stack<int> b;
vector<int> lbu[N],rbu[N];
ll backup[N];
ll ans=linf;
void modify2(int tree[],int p,int l,int r,int x,int v) {
if (l>r) return;
if (x<l||x>r) return;
if (l==r) {
tree[p]=v;
return;
}
int mid=(l+r)/2;
if (x<=mid) modify2(tree,2*p,l,mid,x,v);
else modify2(tree,2*p+1,mid+1,r,x,v);
tree[p]=max(tree[2*p],tree[2*p+1]);
}
int query2(int tree[],int p,int l,int r,int L,int R) {
if (l>r||L>R) return 0;
if (L<l||R>r) return 0;
if (l==L&&r==R) return tree[p];
int mid=(l+r)/2;
if (R<=mid) return query2(tree,2*p,l,mid,L,R);
else if (L>mid) return query2(tree,2*p+1,mid+1,r,L,R);
else return max(query2(tree,2*p,l,mid,L,mid),query2(tree,2*p+1,mid+1,r,mid+1,R));
}
ll query(ll tree[],int p,int l,int r,int L,int R) {
if (l>r||L>R) return 0;
if (L<l||R>r) return 0;
if (l==L&&r==R) return tree[p];
int mid=(l+r)/2;
if (R<=mid) return query(tree,2*p,l,mid,L,R);
else if (L>mid) return query(tree,2*p+1,mid+1,r,L,R);
else return min(query(tree,2*p,l,mid,L,mid),query(tree,2*p+1,mid+1,r,mid+1,R));
}
void modify(ll tree[],int p,int l,int r,int x,ll v) {
if (l>r) return;
if (x<l||x>r) return;
if (l==r) {
tree[p]=v;
return;
}
int mid=(l+r)/2;
if (x<=mid) modify(tree,2*p,l,mid,x,v);
else modify(tree,2*p+1,mid+1,r,x,v);
tree[p]=min(tree[2*p],tree[2*p+1]);
}
void update(ll tree[][4*N],int p,int l,int r,int x,ll v) {
modify(tree[0],p,l,r,x,v);
if (v!=linf) modify(tree[1],p,l,r,x,v+rec[x]);
else modify(tree[1],p,l,r,x,linf);
if (v!=linf) modify(tree[2],p,l,r,x,v-rec[x]);
else modify(tree[2],p,l,r,x,linf);
}
void del(ll tree[][4*N],int p,int l,int r,int x) {
update(tree,p,l,r,x,linf);
}
int find(ll h) {
int l=1,r=m2;
int mid,ok=0;
while (l<=r) {
mid=(l+r)/2;
if (rec[mid]<=h) {
ok=mid;
l=mid+1;
} else r=mid-1;
}
return ok;
}
int find2(int tree[],ll h) {
int x=find(h);
if (x==0) return 0;
return query2(tree,1,1,m2,1,x);
}
ll add(ll x,ll y) {
if (x==linf||y==linf) return linf;
return x+y;
}
void compute(int x,int o) {
int sl=0,sr=0,gl=0,gr=0;
if (o==0) {
sl=x;
for (auto &it:lbu[sl]) {
int x=find2(slp,h[it]);
int t=find2(slp,h[sl]);
if (x&&t&&x<=t) {
ll v=query(slt[0],1,1,m2,x,x);
ll v2=add(query(slt[1],1,1,m2,x,t),-rec[x]);
if (v2<v) update(slt,1,1,m2,x,v2);
}
}
for (auto &it:lb[sl]) {
modify2(slp,1,1,m2,to[it],to[it]);
ll v=query(slt[0],1,1,m2,to[it],to[it]);
int x=find2(slp,h[sl]);
ll v2=linf;
if (x) v2=add(query(slt[1],1,1,m2,to[it],x),-rec[to[it]]);
ll v3=add(query(slt[2],1,1,m2,1,to[it]),rec[to[it]]);
ll v4=min(v,min(v2,v3));
backup[to[it]]=v4;
}
if (sl!=1) for (auto &it:rb[sl]) {
int x=find2(slp,rec[to[it]]-1);
if (x) {
ll v=query(slt[0],1,1,m2,x,x);
ll v2=add(query(slt[1],1,1,m2,to[it],to[it]),-rec[x]);
if (v2<v) update(slt,1,1,m2,x,v2);
}
modify2(slp,1,1,m2,to[it],0);
del(slt,1,1,m2,to[it]);
}
for (auto &it:lb[sl]) {
modify2(slp,1,1,m2,to[it],to[it]);
ll v4=backup[to[it]];
if (v4!=linf) update(slt,1,1,m2,to[it],v4);
}
} else if (o==1) {
sr=x;
for (auto &it:rbu[sr]) {
int x=find2(srp,h[it]);
int t=find2(srp,h[sr]);
if (x&&t&&x<=t) {
ll v=query(srt[0],1,1,m2,x,x);
ll v2=add(query(srt[1],1,1,m2,x,t),-rec[x]);
if (v2<v) update(srt,1,1,m2,x,v2);
}
}
for (auto &it:rb[sr]) {
modify2(srp,1,1,m2,to[it],to[it]);
ll v=query(srt[0],1,1,m2,to[it],to[it]);
int x=find2(srp,h[sr]);
ll v2=linf;
if (x) v2=add(query(srt[1],1,1,m2,to[it],x),-rec[to[it]]);
ll v3=add(query(srt[2],1,1,m2,1,to[it]),rec[to[it]]);
ll v4=min(v,min(v2,v3));
backup[to[it]]=v4;
}
if (sr!=n) for (auto &it:lb[sr]) {
int x=find2(srp,rec[to[it]]-1);
if (x) {
ll v=query(srt[0],1,1,m2,x,x);
ll v2=add(query(srt[1],1,1,m2,to[it],to[it]),-rec[x]);
if (v2<v) update(srt,1,1,m2,x,v2);
}
modify2(srp,1,1,m2,to[it],0);
del(srt,1,1,m2,to[it]);
}
for (auto &it:rb[sr]) {
modify2(srp,1,1,m2,to[it],to[it]);
ll v4=backup[to[it]];
if (v4!=linf) update(srt,1,1,m2,to[it],v4);
}
} else if (o==2) {
gl=x;
for (auto &it:lbu[gl]) {
int x=find2(glp,h[it]);
int t=find2(glp,h[gl]);
if (x&&t&&x<=t) {
ll v=query(glt[0],1,1,m2,x,x);
ll v2=add(query(glt[1],1,1,m2,x,t),-rec[x]);
if (v2<v) update(glt,1,1,m2,x,v2);
}
}
for (auto &it:lb[gl]) {
modify2(glp,1,1,m2,to[it],to[it]);
ll v=query(glt[0],1,1,m2,to[it],to[it]);
int x=find2(glp,h[gl]);
ll v2=linf;
if (x) v2=add(query(glt[1],1,1,m2,to[it],x),-rec[to[it]]);
ll v3=add(query(glt[2],1,1,m2,1,to[it]),rec[to[it]]);
ll v4=min(v,min(v2,v3));
backup[to[it]]=v4;
}
if (gl!=1) for (auto &it:rb[gl]) {
int x=find2(glp,rec[to[it]]-1);
if (x) {
ll v=query(glt[0],1,1,m2,x,x);
ll v2=add(query(glt[1],1,1,m2,to[it],to[it]),-rec[x]);
if (v2<v) update(glt,1,1,m2,x,v2);
}
modify2(glp,1,1,m2,to[it],0);
del(glt,1,1,m2,to[it]);
}
for (auto &it:lb[gl]) {
modify2(glp,1,1,m2,to[it],to[it]);
ll v4=backup[to[it]];
if (v4!=linf) update(glt,1,1,m2,to[it],v4);
}
} else if (o==3) {
gr=x;
for (auto &it:rbu[gr]) {
int x=find2(grp,h[it]);
int t=find2(grp,h[gr]);
if (x&&t&&x<=t) {
ll v=query(grt[0],1,1,m2,x,x);
ll v2=add(query(grt[1],1,1,m2,x,t),-rec[x]);
if (v2<v) update(grt,1,1,m2,x,v2);
}
}
for (auto &it:rb[gr]) {
modify2(grp,1,1,m2,to[it],to[it]);
ll v=query(grt[0],1,1,m2,to[it],to[it]);
int x=find2(grp,h[gr]);
ll v2=linf;
if (x) v2=add(query(grt[1],1,1,m2,to[it],x),-rec[to[it]]);
ll v3=add(query(grt[2],1,1,m2,1,to[it]),rec[to[it]]);
ll v4=min(v,min(v2,v3));
backup[to[it]]=v4;
}
if (gr!=n) for (auto &it:lb[gr]) {
int x=find2(grp,rec[to[it]]-1);
if (x) {
ll v=query(grt[0],1,1,m2,x,x);
ll v2=add(query(grt[1],1,1,m2,to[it],to[it]),-rec[x]);
if (v2<v) update(grt,1,1,m2,x,v2);
}
modify2(grp,1,1,m2,to[it],0);
del(grt,1,1,m2,to[it]);
}
for (auto &it:rb[gr]) {
modify2(grp,1,1,m2,to[it],to[it]);
ll v4=backup[to[it]];
if (v4!=linf) update(grt,1,1,m2,to[it],v4);
}
}
}
long long min_distance(std::vector<int> X, std::vector<int> H, std::vector<int> L, std::vector<int> R, std::vector<int> Y, int ss, int gg) {
s=ss+1;
g=gg+1;
n=X.size(),m=Y.size();
FOR(i,n) x[i]=X[i-1],h[i]=H[i-1];
FOR(i,m) e[i].l=L[i-1]+1,e[i].r=R[i-1]+1,e[i].y=Y[i-1];
sort(e+1,e+1+m,cmp);
if (s>g) swap(s,g);
// 离散化
FOR(i,m) {
if (i==1||e[i].y!=e[i-1].y) rec[++m2]=e[i].y;
to[i]=m2;
}
// 建筑的左右天桥
FOR(i,m) {
lb[e[i].r].pb(i);
rb[e[i].l].pb(i);
}
// 从高到低排序以便弹出天桥的时候自上而下继承更新
FOR(i,n) sort(lb[i].begin(),lb[i].end(),cmp2);
FOR(i,n) sort(rb[i].begin(),rb[i].end(),cmp2);
// 跨越s横坐标的天桥
FOR(i,m) if (e[i].l<=s&&e[i].r>=s) c.pb(i);
FOR(i,m) if (e[i].l<=g&&e[i].r>=g) d.pb(i);
ch=0,ct=(int)c.size()-1,dh=0,dt=(int)d.size()-1;
// 预处理从建筑i能看到的所有建筑j(从左或者从右)
REP(i,s,n) {
while (!b.empty()&&h[b.top()]<h[i]) b.pop();
if (!b.empty()) {
int x=b.top();
rbu[x].pb(i);
}
b.push(i);
}
while (!b.empty()) b.pop();
for (int i=s;i>=1;i--) {
while (!b.empty()&&h[b.top()]<h[i]) b.pop();
if (!b.empty()) {
int x=b.top();
lbu[x].pb(i);
}
b.push(i);
}
while (!b.empty()) b.pop();
// 初始化停留在s,g的扫描线
FOR(i,m2) {
del(slt,1,1,m2,i);
del(srt,1,1,m2,i);
}
FOR(i,m2) {
del(glt,1,1,m2,i);
del(grt,1,1,m2,i);
}
while (ch<=ct&&e[c[ch]].y<=h[s]) {
int u=to[c[ch]];
update(slt,1,1,m2,u,e[c[ch]].y);
update(srt,1,1,m2,u,e[c[ch]].y);
modify2(slp,1,1,m2,u,u);
modify2(srp,1,1,m2,u,u);
ch++;
}
while (dh<=dt&&e[d[dh]].y<=h[g]) {
int u=to[d[dh]];
update(glt,1,1,m2,u,e[d[dh]].y);
update(grt,1,1,m2,u,e[d[dh]].y);
modify2(glp,1,1,m2,u,u);
modify2(grp,1,1,m2,u,u);
dh++;
}
// 扩展扫描矩形
su.l=s,su.r=s,gu.l=g,gu.r=g;
su.maxh=h[s],gu.maxh=h[g];
while (1) {
if (turn==0) {
if (su.r==n) break;
compute(su.r,1); // 把之前的扫描线更新为新的扫描线作准备
su.r++;
if (su.r>=g) turn=1;
while (h[su.r]>su.maxh) {
while (su.l>=1) {
if (h[su.l]>su.maxh) {
su.maxh=min(h[su.l],h[su.r]);
while (ch<=ct&&e[c[ch]].y<=su.maxh) {
int u=to[c[ch]];
ll vl=add(query(slt[2],1,1,m2,1,u),e[c[ch]].y+x[s]-x[su.l]);
ll vr=add(query(srt[2],1,1,m2,1,u),e[c[ch]].y+x[su.r]-x[s]);
modify2(slp,1,1,m2,u,u);
modify2(srp,1,1,m2,u,u);
if (vl!=linf) update(slt,1,1,m2,u,vl-(x[s]-x[su.l]));
if (vr!=linf) update(srt,1,1,m2,u,vr-(x[su.r]-x[s]));
if (vl!=linf&&vl+x[su.r]-x[su.l]<vr) update(srt,1,1,m2,u,vl+x[su.r]-x[su.l]-(x[su.r]-x[s]));
else if (vr!=linf&&vr+x[su.r]-x[su.l]<vl) update(slt,1,1,m2,u,vr+x[su.r]-x[su.l]-(x[s]-x[su.l]));
ch++;
}
break;
} else {
compute(su.l,0);
if (su.l>1) su.l--;
else {
su.maxh=h[su.r];
break;
}
}
}
}
} else {
ll v1,v2;
v1=v2=linf;
int j=find2(srp,h[su.r]),k;
if (j) {
v1=add(query(srt[1],1,1,m2,1,j),x[su.r]-x[s]);
k=find2(grp,min(rec[j],h[gu.r]));
}
if (k) v2=add(query(grt[2],1,1,m2,1,k),x[gu.r]-x[g]);
ans=min(ans,add(v1,v2));
if (gu.r==n) break;
compute(gu.r,3);
gu.r++;
turn=0;
while (h[gu.r]>gu.maxh) {
while (gu.l>=1) {
if (h[gu.l]>gu.maxh) {
gu.maxh=min(h[gu.l],h[gu.r]);
while (dh<=dt&&e[d[dh]].y<=gu.maxh) {
int u=to[d[dh]];
ll vl=add(query(glt[2],1,1,m2,1,u),e[d[dh]].y+x[g]-x[gu.l]);
ll vr=add(query(grt[2],1,1,m2,1,u),e[d[dh]].y+x[gu.r]-x[g]);
modify2(glp,1,1,m2,u,u);
modify2(grp,1,1,m2,u,u);
if (vl!=linf) update(glt,1,1,m2,u,vl-(x[g]-x[gu.l]));
if (vr!=linf) update(grt,1,1,m2,u,vr-(x[gu.r]-x[g]));
if (vl!=linf&&vl+x[gu.r]-x[gu.l]<vr) update(grt,1,1,m2,u,vl+x[gu.r]-x[gu.l]-(x[gu.r]-x[g]));
else if (vr!=linf&&vr+x[gu.r]-x[gu.l]<vl) update(glt,1,1,m2,u,vr+x[gu.r]-x[gu.l]-(x[g]-x[gu.l]));
dh++;
}
break;
} else {
compute(gu.l,2);
if (gu.l>1) gu.l--;
else {
gu.maxh=h[gu.r];
break;
}
}
}
}
}
}
if (ans==linf) ans=-1;
return ans;
}
Compilation message (stderr)
walk.cpp: In function 'long long int min_distance(std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, int, int)':
walk.cpp:389:17: warning: 'k' may be used uninitialized in this function [-Wmaybe-uninitialized]
389 | if (k) v2=add(query(grt[2],1,1,m2,1,k),x[gu.r]-x[g]);
| ~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |