Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #include <ext/pb_ds/assoc_container.hpp>
- #include <ext/pb_ds/tree_policy.hpp>
- #define uint unsigned int
- #define ld long double
- #define ll long long
- #define ull unsigned long long
- #define F first
- #define S second
- #define pb push_back
- #define sqr(x) (x) * (x)
- using namespace std;
- using namespace __gnu_pbds;
- mt19937 gen(time(0));
- const int maxn = 1048576;
- int inf = 1e9 + 7;
- struct segtree
- {
- int T[maxn * 2];
- int mx[maxn * 2];
- int lazy[maxn * 2];
- segtree()
- {
- for(int i = 0; i < maxn * 2; ++i)
- mx[i] = -inf;
- }
- void update(int v, int tl, int tr, int p, int x)
- {
- if (tl == tr)
- {
- T[v] = x;
- mx[v] = x;
- return;
- }
- int mid = (tl + tr) / 2;
- if (p <= mid) update(v << 1, tl, mid, p, x);
- else update(v << 1 | 1, mid + 1, tr, p, x);
- T[v] = min(T[v << 1], T[v << 1 | 1]);
- mx[v] = max(mx[v << 1], mx[v << 1 | 1]);
- return;
- }
- int query(int v, int tl, int tr, int l, int r)
- {
- if (tr < l || tl > r) return inf;
- if (tl >= l && tr <= r) return T[v];
- int mid = (tl + tr) / 2;
- return min(query(v << 1, tl, mid, l, r),
- query(v << 1 | 1, mid + 1, tr, l, r));
- }
- //ubrat
- int binleft(int v, int tl, int tr, int p, int x)
- {
- if (tl == tr)
- {
- if (tl <= p && mx[v] >= x)
- return tl;
- else
- return -1;
- }
- int mid = (tl + tr) / 2;
- int ans = -1;
- if (p >= mid + 1 && mx[v << 1 | 1] >= x)
- ans = binleft(v << 1 | 1, mid + 1, tr, p, x);
- if (p >= tl && mx[v << 1] >= x && ans == -1)
- ans = binleft(v << 1, tl, mid, p, x);
- return ans;
- }
- int binright(int v, int tl, int tr, int p, int x)
- {
- if (tl == tr)
- {
- if (tl >= p && mx[v] >= x)
- return tl;
- else
- return -1;
- }
- int mid = (tl + tr) / 2;
- int ans = -1;
- if (p <= mid && mx[v << 1] >= x)
- ans = binright(v << 1, tl, mid, p, x);
- if (p <= tr && mx[v << 1 | 1] >= x && ans == -1)
- ans = binright(v << 1 | 1, mid + 1, tr, p, x);
- return ans;
- }
- };
- segtree t1, t2;
- int main()
- {
- #ifdef LOCAL
- freopen("input.txt", "r", stdin);
- freopen("output.txt", "w", stdout);
- #else
- freopen("input.txt", "r", stdin);
- freopen("output.txt", "w", stdout);
- #endif
- ios_base::sync_with_stdio(false);
- cin.tie(0);
- cout.tie(0);
- int n, m, q;
- cin >> n >> m >> q;
- for(int i = 0; i < q; ++i)
- {
- int t;
- cin >> t;
- if(t == 1)
- {
- int r;
- cin >> r;
- --r;
- t1.update(1, 0, maxn - 1, r, i + 1);
- }
- if(t == 2)
- {
- int c;
- cin >> c;
- --c;
- t2.update(1, 0, maxn - 1, c, i + 1);
- }
- if (t == 3)
- {
- int ans = inf;
- int r1, c1, r2, c2, k;
- cin >> r1 >> c1 >> r2 >> c2 >> k;
- --r1;
- --r2;
- --c1;
- --c2;
- {
- vector <pair <pair <int, int>, int>> vc1;
- vector <pair <pair <int, int>, int>> vc2;
- vc1.pb({{r1, c1}, 0});
- vc2.pb({{r2, c2}, 0});
- {
- bool f1 = false;
- bool f2 = false;
- if (i + 1 - t2.T[c1 + maxn] <= k) f1 = true;
- if (i + 1 - t2.T[c2 + maxn] <= k) f2 = true;
- int R1 = t1.binleft(1, 0, maxn - 1, r1 - 1, i + 1 - k);
- int R2 = t1.binright(1, 0, maxn - 1, r1 + 1, i + 1 - k);
- int RR1 = t1.binleft(1, 0, maxn - 1, r2 - 1, i + 1 - k);
- int RR2 = t1.binright(1, 0, maxn - 1, r2 + 1, i + 1 - k);
- if (R1 > -1 && f1) vc1.pb({{R1, c1}, r1 - R1});
- if (R2 > -1 && f1) vc1.pb({{R2, c1}, R2 - r1});
- if (RR1 > -1 && f2) vc2.pb({{RR1, c2}, r2 - RR1});
- if (RR2 > -1 && f2) vc2.pb({{RR2, c2}, RR2 - r2});
- }
- {
- bool f1 = false;
- bool f2 = false;
- if (i + 1 - t1.T[r1 + maxn] <= k) f1 = true;
- if (i + 1 - t1.T[r2 + maxn] <= k) f2 = true;
- int C1 = t2.binleft(1, 0, maxn - 1, c1 - 1, i + 1 - k);
- int C2 = t2.binright(1, 0, maxn - 1, c1 + 1, i + 1 - k);
- int CC1 = t2.binleft(1, 0, maxn - 1, c2 - 1, i + 1 - k);
- int CC2 = t2.binright(1, 0, maxn - 1, c2 + 1, i + 1 - k);
- if (C1 > -1 && f1) vc1.pb({{r1, C1}, c1 - C1});
- if (C2 > -1 && f1) vc1.pb({{r1, C2}, C2 - c1});
- if (CC1 > -1 && f2) vc2.pb({{r2, CC1}, c2 - CC1});
- if (CC2 > -1 && f2) vc2.pb({{r2, CC2}, CC2 - c2});
- }
- for(int j = 0; j < int(vc1.size()); ++j)
- for(int jj = 0; jj < int(vc2.size()); ++jj)
- {
- int R1 = vc1[j].F.F;
- int C1 = vc1[j].F.S;
- int R2 = vc2[jj].F.F;
- int C2 = vc2[jj].F.S;
- int dep = vc1[j].S + vc2[jj].S + abs(R1 - R2) + abs(C1 - C2);
- if ((i + 1 - t1.T[R1 + maxn] <= k && i + 1 - t2.T[C2 + maxn] <= k) || (i + 1 - t2.T[C1 + maxn] <= k && i + 1 - t1.T[R2 + maxn] <= k) ||
- i + 1 - t1.query(1, 0, maxn - 1, min(R1, R2), max(R1, R2)) <= k || i + 1 - t2.query(1, 0, maxn - 1, min(C1, C2), max(C1, C2)) <= k)
- ans = min(ans, dep);
- }
- }
- if (ans == inf) cout << "-1\n";
- else cout << ans << '\n';
- }
- }
- return 0;
- }
- //
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement