Submission #1330109

#TimeUsernameProblemLanguageResultExecution timeMemory
1330109enzySky Walking (IOI19_walk)C++20
33 / 100
357 ms75496 KiB
#include "walk.h"
#include<bits/stdc++.h>
#define ll long long
#define sz(v) (int)(v.size())
#define pii pair<int,int>
#define fi first
#define se second
using namespace std;
const int inf=1e9+7;
const ll INF=1e16;

struct node{
	ll s1, resp, s2;
};

class SparseSeg{
protected:
	vector<node>seg;
	vector<int> e, d;
public:
	int cria(){
		seg.push_back({INF,INF,INF});
		e.push_back(0);
		d.push_back(0);
		return sz(seg)-1;
	}
	SparseSeg() { cria(); cria();}
	
	int getLeft(int id){
		if(e[id]) return e[id];
		return e[id]=cria();
	}

	int getRight(int id){
		if(d[id]) return d[id];
		return d[id]=cria();
	}

	node merge(node e, node d){
		node ret;
		ret.s1=min(e.s1,d.s1); ret.resp=min(e.resp,d.resp); ret.s2=min(e.s2,d.s2);
		return ret;
	}

	void update(int id, ll ini, ll fim, int cara, ll val){
		if(ini==fim){
			seg[id].s1=val-ini;
			seg[id].s2=val+ini;
			seg[id].resp=val;
			return;
		}
		int mid=(ini+fim)/2;
		if(cara<=mid) update(getLeft(id),ini,mid,cara,val);
		else update(getRight(id),mid+1,fim,cara,val);
		seg[id]=merge(seg[e[id]],seg[d[id]]);
	}

	node query(int id, ll ini, ll fim, int l, int r){
		if(ini>r||fim<l) return seg[0];
		if(l<=ini&&fim<=r) return seg[id];
		int mid=(ini+fim)/2;
		return merge(query(e[id],ini,mid,l,r),query(d[id],mid+1,fim,l,r));
	}
};
SparseSeg ds;

ll min_distance(vector<int> x, vector<int> h, vector<int> l, vector<int> r, vector<int> y, int s, int g){
	int n=sz(x), m=sz(l);
	vector<vector<pii>>v(n);
	for(int i=0;i<m;i++) v[l[i]].push_back({y[i],r[i]});
	set<pii>ends;
	ends.insert({0,0});
	ds.update(1,0,inf,0,0);
	map<int,int>mp;
	for(int i=0;i<n-1;i++){
		for(pii p : v[i]){
			if(mp[p.fi]>=i&&i){
				if(mp[p.fi]<p.se){
					ends.erase({mp[p.fi],p.fi});
					mp[p.fi]=p.se;
					ends.insert({mp[p.fi],p.fi});
				}
			}else{
				node l=ds.query(1,0,inf,0,p.fi-1), r=ds.query(1,0,inf,p.fi+1,inf);
				ll cost=min(l.s1+p.fi,r.s2-p.fi);
				// cout << i << ' ' << p.se << ' ' << p.fi << ' ' << cost << '\n';
				if(cost<INF){ 
					ds.update(1,0,inf,p.fi,cost);
					mp[p.fi]=p.se;
					ends.insert({mp[p.fi],p.fi});
				}
			}
		}
		while(sz(ends)){
			auto f=ends.begin();
			int u=f->first;
			if(u>i) break;
			int z=f->second;
			ends.erase(f);
			ds.update(1,0,inf,z,INF);
		}
	}
	if(ds.query(1,0,inf,0,inf).s2>=INF) return -1;
	ll add=x.back()-x[0];
	return ds.query(1,0,inf,0,inf).s2+add;
}
#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...