# |
Submission time |
Handle |
Problem |
Language |
Result |
Execution time |
Memory |
1111120 |
2024-11-11T14:34:00 Z |
doducanh |
Walk (CEOI06_walk) |
C++14 |
|
106 ms |
13484 KB |
///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 |
1 |
Correct |
1 ms |
336 KB |
Output is correct |
2 |
Correct |
1 ms |
336 KB |
Output is correct |
3 |
Correct |
1 ms |
504 KB |
Output is correct |
4 |
Correct |
2 ms |
592 KB |
Output is correct |
5 |
Correct |
86 ms |
12472 KB |
Output is correct |
6 |
Correct |
30 ms |
3968 KB |
Output is correct |
7 |
Correct |
58 ms |
6852 KB |
Output is correct |
8 |
Correct |
106 ms |
12460 KB |
Output is correct |
9 |
Correct |
101 ms |
13368 KB |
Output is correct |
10 |
Correct |
106 ms |
13484 KB |
Output is correct |