# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
1111120 | doducanh | Walk (CEOI06_walk) | C++14 | 106 ms | 13484 KiB |
This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
///breaker
#pragma GCC optimize("O2")
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define fi first
#define se second
#define ii pair<int,int>
#define mp make_pair
#define in(x) freopen(x,"r",stdin)
#define out(x) freopen(x,"w",stdout)
#define bit(x,i) ((x>>i)&1)
#define lc (id<<1)
#define rc ((id<<1)^1)
const int maxn=1e5+7;
struct info
{
int x1,x2,y1,y2;
int x;
int id;
int link1,link2;
};
struct event
{
int id,y,type;
};
bool cmpx2(const info &a,const info &b)
{
return a.x2<b.x2;
}
struct segtree
{
vector<int>t;
int n;
segtree(int N)
{
n=N;
t.resize(4*N,-1);
}
void add(int id,int l,int r,int u,int val)
{
if(l>u||r<u)return;
if(l==r){
t[id]=val;
return;
}
int m=(l+r)/2;
if(u<=m)add(lc,l,m,u,val);
else add(rc,m+1,r,u,val);
t[id]=max(t[lc],t[rc]);
}
int get(int id,int l,int r,int u)
{
if(l>u)return -1;
if(r<=u)return t[id];
int m=(l+r)/2;
return max(get(lc,l,m,u),get(rc,m+1,r,u));
}
void era(int id,int l,int r,int u)
{
if(l>u||r<u)return;
if(l==r){
t[id]=-1;
return;
}
int m=(l+r)/2;
if(u<=m)era(lc,l,m,u);
else era(rc,m+1,r,u);
t[id]=max(t[lc],t[rc]);
}
void add(int u,int val){add(1,0,n,u,val);}
int get(int u){return get(1,0,n,u);}
void era(int u){era(1,0,n,u);}
};
int X,Y;
int n;
ii dp[maxn];
vector<ii>sol;
vector<info>a(n);
void backtrack(int &link,int &ans)
{
if(link==-1){
sol.push_back({X,0}),X=0;
sol.push_back({0,Y}),Y=0;
return;
}
if( ans == X-a[link].x2-1 + abs( Y - a[link].y1+1 ) + dp[link].first ) {
int dx = X - a[link].x2-1;
int dy = Y - a[link].y1+1;
if( dx ) { sol.push_back( pair<int,int> (dx, 0) ); X -= dx; }
if( dy ) { sol.push_back( pair<int,int> (0, dy) ); Y -= dy; }
ans = dp[link].first;
link = a[link].link1;
} else {
int dx = X - a[link].x2-1;
int dy = Y - a[link].y2-1;
if( dx ) { sol.push_back( pair<int,int> (dx, 0) ); X -= dx; }
if( dy ) { sol.push_back( pair<int,int> (0, dy) ); Y -= dy; }
ans = dp[link].second;
link = a[link].link2;
}
}
void solve(void){
cin>>X>>Y;
cin>>n;
a.resize(n);
for(int i=0;i<n;i++){
cin>>a[i].x1>>a[i].y1>>a[i].x2>>a[i].y2;
a[i].link1=-1;
a[i].link2=-1;
if(a[i].x1>a[i].x2)swap(a[i].x1,a[i].x2);
if(a[i].y1>a[i].y2)swap(a[i].y1,a[i].y2);
}
sort(a.begin(),a.end(),cmpx2);
int cnt=0;
int lastx=-1;
vector<event>events;
for(int i=0;i<n;i++){
a[i].id=i;
if(a[i].x2!=lastx){
cnt++;
}
a[i].x=cnt;
lastx=a[i].x2;
events.push_back({i,a[i].y1,0});
events.push_back({i,a[i].y1-1,1});
events.push_back({i,a[i].y2+1,2});
events.push_back({i,a[i].y2,3});
}
sort(events.begin(),events.end(),[&](event &a, event &b){
return (a.y<b.y)||(a.y==b.y&&a.type<b.type);
});
segtree t(cnt+1);
for(event tmp:events){
if(tmp.type==0){
t.add(a[tmp.id].x,tmp.id);
}
else if(tmp.type==1){
a[tmp.id].link1=t.get(a[tmp.id].x);
}
else if(tmp.type==2){
a[tmp.id].link2=t.get(a[tmp.id].x);
}
else{
t.era(a[tmp.id].x);
}
}
for(int i=0;i<n;i++){
int j=a[i].link1;
if(j==-1){
dp[i].fi=a[i].x2+1+abs(a[i].y1-1);
}
else{
dp[i].fi=min(dp[j].fi+a[i].x2-a[j].x2+abs(a[i].y1-1-a[j].y1+1),dp[j].se+a[i].x2-a[j].x2+abs(a[i].y1-1-a[j].y2-1));
}
j=a[i].link2;
if(j==-1){
dp[i].se=a[i].x2+1+abs(a[i].y2+1);
}
else{
dp[i].se=min(dp[j].fi+a[i].x2-a[j].x2+abs(a[i].y2+1-a[j].y1+1),dp[j].se+a[i].x2-a[j].x2+abs(a[i].y2+1-a[j].y2-1));
}
}
int ans=X+abs(Y);
int link=-1;
for(int i=n-1;i>=0;i--){
if(a[i].x2<X&&a[i].y1<=Y&&Y<=a[i].y2){
link=i;
break;
}
}
if(link!=-1){
ans=min(X-a[link].x2-1+abs(Y-a[link].y1+1)+dp[link].fi,X-a[link].x2-1+abs(Y-a[link].y2-1)+dp[link].se);
}
cout<<ans<<"\n";
if(link!=-1){
while(X!=0||Y!=0){
backtrack(link,ans);
}
}
cout<<sol.size()<<"\n";
for(int i=sol.size()-1;i>=0;i--){
cout<<sol[i].fi<<" "<<sol[i].se<<"\n";
}
}
signed main(){
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t=1;
while(t--){
solve();
}
// you should actually read the stuff at the bottom
return 0;
}
/* stuff you should look for
* int overflow, array bounds
* special cases (n=1?)
* do smth instead of nothing and stay organized
* WRITE STUFF DOWN
* DON'T GET STUCK ON ONE APPROACH
*/
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |