Submission #1111120

#TimeUsernameProblemLanguageResultExecution timeMemory
1111120doducanhWalk (CEOI06_walk)C++14
100 / 100
106 ms13484 KiB
///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 timeMemoryGrader output
Fetching results...