#include <bits/extc++.h>
using namespace std;
using namespace __gnu_pbds;
#ifdef _DEBUG
#define dout(x) clog << "Line " << __LINE__ << ": " << #x << "=" << (x) << el
#else
#define dout(x)
#endif
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define uid(a,b) uniform_int_distribution<int>(a,b)(rng)
#define ins insert
#define ssize(x) (int((x).size()))
#define bs(args...) binary_search(args)
#define lb(args...) lower_bound(args)
#define ub(args...) upper_bound(args)
#define all(x) (x).begin(),(x).end()
#define mp(a, b) make_pair(a, b)
#define mt(args...) make_tuple(args)
#define pb push_back
#define eb emplace_back
#define ff first
#define ss second
#define die exit(0)
template<typename T>
using vc = vector<T>;
template<typename T>
using uset = unordered_set<T>;
template<typename A, typename B>
using umap = unordered_map<A, B>;
template<typename T, typename Comp>
using pq = std::priority_queue<T, vc<T>, Comp>;
template<typename T>
using maxpq = pq<T, less<T>>;
template<typename T>
using minpq = pq<T, greater<T>>;
template<typename T>
using oset = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
using db = double;
using ld = long double;
using ll = long long;
using ull = unsigned long long;
using pi = pair<int, int>;
using pll = pair<ll, ll>;
using pdb = pair<db, db>;
using pld = pair<ld, ld>;
using vi = vc<int>;
using vll = vc<ll>;
using vpi = vc<pi>;
using vpll = vc<pll>;
using vpdb = vc<pdb>;
using vpld = vc<pld>;
using str = string;
constexpr char el = '\n';
constexpr char sp = ' ';
constexpr int inf = 0x3f3f3f3f;
constexpr ll llinf = 0x3f3f3f3f3f3f3f3fLL;
// ---------------------------------------------------------------------
const int N = 1e5+5;
int n, dx, dy, a[N], b[N], c[N], d[N], nxt[N][2], g[N][4], ans;
struct segtree {
int size = 1<<21, tr[(1<<22)+100];
segtree() {
memset(tr, -1, sizeof tr);
}
void push(int i){
if(tr[i] == -1) return;
if(i < size) {
tr[2 * i] = tr[2 * i + 1] = tr[i];
tr[i] = -1;
}
}
void set(int l, int r, int i, int il, int ir, int x){
if(ir < l || r < il)
return;
if(l <= il && ir <= r){
tr[i] = x;
return;
}
push(i);
int im = (il+ir)/2;
set(l, r, 2*i, il, im, x);
set(l, r, 2*i+1, im+1, ir, x);
}
void set(int l, int r, int x){
set(l, r, 1, 0, size-1, x);
}
int get(int i){
int ans=-1;
i += size;
while(i>0){
if(tr[i] != -1)
ans = tr[i];
i /= 2;
}
return ans;
}
}seg;
vpi mov;
int dis(int x, int y, int x2, int y2){
return abs(x-x2) + abs(y-y2);
}
void evan2(int x, int y, int x2, int y2){
ans += abs(x-x2) + abs(y-y2);
if(x != x2)
mov.eb(x2-x, 0);
if(y!=y2)
mov.eb(0, y2-y);
assert(ssize(mov)<=int(1e6));
}
void evan3(int x, int y, int j){
if(j==-1){
evan2(0, 1e6+1, x, y);
return;
}
int option_down = g[j][2] + dis(c[j], b[j], x, y);
int option_up = g[j][3] + dis(c[j], d[j], x, y);
if(option_down < option_up){
evan3(c[j], b[j], nxt[j][0]);
evan2(c[j], b[j], x, y);
}else{
evan3(c[j], d[j], nxt[j][1]);
evan2(c[j], d[j], x, y);
}
}
void evan(int i){
if(i==-1)
return;
int j = nxt[i][0];
if(j==-1)
g[i][0] = dis(0, 1e6+1, a[i], b[i]);
else{
evan(j);
g[i][0] = min(g[j][2] + dis(c[j], b[j], a[i], b[i]),
g[j][3] + dis(c[j], d[j], a[i], b[i]));
}
j = nxt[i][1];
if(j==-1)
g[i][1] = dis(0, 1e6+1, a[i], d[i]);
else{
if(nxt[i][0] != nxt[i][1])
evan(j);
g[i][1] = min(g[j][2] + dis(c[j], b[j], a[i], d[i]),
g[j][3] + dis(c[j], d[j], a[i], d[i]));
}
g[i][2] = dis(a[i], b[i], c[i], b[i]) + g[i][0];
g[i][3] = dis(c[i], d[i], a[i], d[i]) + g[i][1];
}
signed main() {
ios::sync_with_stdio(0); cin.tie(0);
cout << fixed; clog << fixed; clog << unitbuf;
#ifdef _DEBUG
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
freopen("debug.txt", "w", stderr);
#else
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
#endif
cin >> dx >> dy >> n;
dy += 1e6+1;
vi cc;
vpi e{{dx, -1}};
for(int i = 0; i < n; ++i){
cin >> a[i] >> b[i] >> c[i] >> d[i];
if(a[i] > c[i])
swap(a[i], c[i]);
if(b[i] > d[i])
swap(b[i], d[i]);
e.eb(a[i], i);
--a[i];
--b[i];
++c[i];
++d[i];
b[i] += 1e6+1;
d[i] += 1e6+1;
}
sort(all(e));
int j = -1;
for(auto[x, i]: e){
if(i==-1){
j = seg.get(dy);
break;
}
nxt[i][0] = seg.get(b[i]);
nxt[i][1] = seg.get(d[i]);
seg.set(b[i]+1, d[i]-1, i);
}
if(j !=-1)
evan(j);
int x = dx, y = dy;
while(1){
if(j==-1) {
evan2(0, 1e6 + 1, x, y);
break;
}
int option_down = g[j][2] + dis(c[j], b[j], x, y);
int option_up = g[j][3] + dis(c[j], d[j], x, y);
if(option_down < option_up){
// evan3(c[j], b[j], nxt[j][0]);
evan2(c[j], b[j], x, y);
tie(x, y, j) = mt(c[j], b[j], nxt[j][0]);
}else{
// evan3(c[j], d[j], nxt[j][1]);
evan2(c[j], d[j], x, y);
tie(x, y, j) = mt(c[j], d[j], nxt[j][1]);
}
}
// evan3(dx, dy, j);
cout << ans << el;
cout << ssize(mov) << el;
reverse(all(mov));
for(auto[x, y]: mov)
cout << x << sp << y << el;
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
7 ms |
16724 KB |
Output is correct |
2 |
Correct |
9 ms |
16680 KB |
Output is correct |
3 |
Correct |
8 ms |
16736 KB |
Output is correct |
4 |
Execution timed out |
1087 ms |
16844 KB |
Time limit exceeded |
5 |
Execution timed out |
1088 ms |
20884 KB |
Time limit exceeded |
6 |
Execution timed out |
1088 ms |
18276 KB |
Time limit exceeded |
7 |
Execution timed out |
1082 ms |
18912 KB |
Time limit exceeded |
8 |
Execution timed out |
1090 ms |
20824 KB |
Time limit exceeded |
9 |
Execution timed out |
1095 ms |
21408 KB |
Time limit exceeded |
10 |
Execution timed out |
1083 ms |
21616 KB |
Time limit exceeded |