結果
問題 | No.1920 Territory |
ユーザー | ei1333333 |
提出日時 | 2022-04-29 23:23:14 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 412 ms / 5,000 ms |
コード長 | 7,815 bytes |
コンパイル時間 | 3,122 ms |
コンパイル使用メモリ | 238,680 KB |
実行使用メモリ | 24,616 KB |
最終ジャッジ日時 | 2024-06-29 05:07:29 |
合計ジャッジ時間 | 11,238 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 6 ms
10,292 KB |
testcase_01 | AC | 6 ms
10,164 KB |
testcase_02 | AC | 6 ms
8,016 KB |
testcase_03 | AC | 10 ms
10,360 KB |
testcase_04 | AC | 11 ms
10,484 KB |
testcase_05 | AC | 11 ms
8,328 KB |
testcase_06 | AC | 12 ms
8,584 KB |
testcase_07 | AC | 11 ms
10,364 KB |
testcase_08 | AC | 12 ms
10,484 KB |
testcase_09 | AC | 13 ms
8,448 KB |
testcase_10 | AC | 13 ms
10,364 KB |
testcase_11 | AC | 13 ms
10,360 KB |
testcase_12 | AC | 13 ms
8,480 KB |
testcase_13 | AC | 401 ms
23,256 KB |
testcase_14 | AC | 406 ms
23,540 KB |
testcase_15 | AC | 412 ms
24,616 KB |
testcase_16 | AC | 401 ms
23,668 KB |
testcase_17 | AC | 392 ms
23,252 KB |
testcase_18 | AC | 381 ms
21,772 KB |
testcase_19 | AC | 377 ms
21,400 KB |
testcase_20 | AC | 395 ms
21,588 KB |
testcase_21 | AC | 387 ms
22,584 KB |
testcase_22 | AC | 386 ms
21,524 KB |
testcase_23 | AC | 190 ms
21,336 KB |
testcase_24 | AC | 185 ms
22,796 KB |
testcase_25 | AC | 167 ms
21,792 KB |
testcase_26 | AC | 164 ms
21,632 KB |
testcase_27 | AC | 170 ms
22,288 KB |
testcase_28 | AC | 170 ms
22,904 KB |
testcase_29 | AC | 199 ms
21,716 KB |
testcase_30 | AC | 197 ms
21,732 KB |
testcase_31 | AC | 354 ms
23,196 KB |
testcase_32 | AC | 351 ms
23,396 KB |
testcase_33 | AC | 212 ms
22,536 KB |
testcase_34 | AC | 211 ms
21,848 KB |
ソースコード
// https://atcoder.jp/contests/joi2014ho/submissions/2337234 #include<bits/stdc++.h> using namespace std; using int64 = long long; const int mod = 1e9 + 7; // const int mod = 998244353; const int64 infll = (1LL << 62) - 1; const int inf = (1 << 30) - 1; struct IoSetup { IoSetup() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(10); cerr << fixed << setprecision(10); } } iosetup; template< typename T1, typename T2 > ostream &operator<<(ostream &os, const pair< T1, T2 > &p) { os << p.first << " " << p.second; return os; } template< typename T1, typename T2 > istream &operator>>(istream &is, pair< T1, T2 > &p) { is >> p.first >> p.second; return is; } template< typename T > ostream &operator<<(ostream &os, const vector< T > &v) { for(int i = 0; i < (int) v.size(); i++) { os << v[i] << (i + 1 != v.size() ? " " : ""); } return os; } template< typename T > istream &operator>>(istream &is, vector< T > &v) { for(T &in: v) is >> in; return is; } template< typename T1, typename T2 > inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); } template< typename T1, typename T2 > inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); } template< typename T = int64 > vector< T > make_v(size_t a) { return vector< T >(a); } template< typename T, typename... Ts > auto make_v(size_t a, Ts... ts) { return vector< decltype(make_v< T >(ts...)) >(a, make_v< T >(ts...)); } template< typename T, typename V > typename enable_if< is_class< T >::value == 0 >::type fill_v(T &t, const V &v) { t = v; } template< typename T, typename V > typename enable_if< is_class< T >::value != 0 >::type fill_v(T &t, const V &v) { for(auto &e: t) fill_v(e, v); } template< typename F > struct FixPoint : F { FixPoint(F &&f) : F(forward< F >(f)) {} template< typename... Args > decltype(auto) operator()(Args &&... args) const { return F::operator()(*this, forward< Args >(args)...); } }; template< typename F > inline decltype(auto) MFP(F &&f) { return FixPoint< F >{forward< F >(f)}; } typedef pair< int, int > Point; enum : int { CREATEY, APPEARX, DELETEY }; struct Event { int y, idx, type; bool operator<(const Event &e) const { if(y == e.y) return (type < e.type); return (y < e.y); } }; struct BinaryIndexedTree { vector< int > data; BinaryIndexedTree(int sz) { data.assign(sz + 2, 0); } int query(int k) { int ret = 0; for(++k; k > 0; k -= k & -k) ret += data[k]; return (ret); } void update(int k, int x) { for(++k; k < data.size(); k += k & -k) data[k] += x; } }; struct SegmentTree { vector< int > isnew; int sz; SegmentTree(int n) { sz = 1; while(sz < n) sz <<= 1; isnew.assign(2 * sz - 1, false); } inline void AddF(const int a, const int b, int k, int l, int r) { if(a >= r || b <= l) { return; } else if(a <= l && r <= b) { isnew[k] = true; } else { AddF(a, b, 2 * k + 1, l, (l + r) >> 1); AddF(a, b, 2 * k + 2, (l + r) >> 1, r); } } inline void DelF(const int a, const int b, int k, int l, int r) { if(a >= r || b <= l) { return; } else if(a <= l && r <= a + 1) { isnew[k] = false; } else { if(isnew[k]) { isnew[2 * k + 1] = true; isnew[2 * k + 2] = true; isnew[k] = false; } DelF(a, b, 2 * k + 1, l, (l + r) >> 1); DelF(a, b, 2 * k + 2, (l + r) >> 1, r); } } inline void AddF(int a, int b) { AddF(a, b, 0, 0, sz); } inline void DelF(const int x) { DelF(x, x + 1, 0, 0, sz); } inline bool CheckF(int k) { k += sz - 1; if(isnew[k]) return (true); while(k > 0) { k = (k - 1) >> 1; if(isnew[k]) return (true); } while(k > 0); return (false); } }; struct UnionFind { vector< int > data; UnionFind() {}; inline int Make() { data.push_back(-1); return (data.size() - 1); } inline bool Unite(int a, int b) { a = Find(a), b = Find(b); if(a == b) return (false); if(data[a] > data[b]) swap(a, b); data[a] += data[b]; data[b] = a; return (true); } inline int Find(int k) { if(data[k] < 0) return (k); else return (data[k] = Find(data[k])); } }; SegmentTree *tree; UnionFind *uf; BinaryIndexedTree *bit; int decode[200020]; int Evaluate(int x) { if(tree->CheckF(x)) { tree->DelF(x); return (uf->Make()); } else { return (decode[x]); } } int Press(int *A, int sz1, int *B, int sz2) { vector< int > nums; copy(A, A + sz1, back_inserter(nums)); copy(B, B + sz2, back_inserter(nums)); nums.push_back(-1); sort(nums.begin(), nums.end()); nums.erase(unique(nums.begin(), nums.end()), nums.end()); transform(A, A + sz1, A, [&](int x) { return (lower_bound(nums.begin(), nums.end(), x) - nums.begin()); }); transform(B, B + sz2, B, [&](int x) { return (lower_bound(nums.begin(), nums.end(), x) - nums.begin()); }); return (nums.size()); } auto tap() { int N, M; cin >> N >> M; vector< tuple< int, int, int, int > > seg; { vector< vector< pair< int, int > > > es(200005); for(int i = 0; i < N; i++) { int a, b, c; cin >> a >> b >> c; es[a].emplace_back(b, c); } for(int i = 0; i < es.size(); i++) { sort(begin(es[i]), end(es[i])); int nxt = -1; for(auto&[l, r]: es[i]) { if(nxt < l) { if(~nxt) { get< 2 >(seg.back()) = nxt; } seg.emplace_back(l, i, r, i); } nxt = max(nxt, r); } } } { vector< vector< pair< int, int > > > es(200005); for(int i = 0; i < M; i++) { int a, b, c; cin >> a >> b >> c; es[a].emplace_back(b, c); } for(int i = 0; i < es.size(); i++) { sort(begin(es[i]), end(es[i])); int nxt = -1; for(auto&[l, r]: es[i]) { if(nxt < l) { if(~nxt) { get< 3 >(seg.back()) = nxt; } seg.emplace_back(i, l, i, r); } nxt = max(nxt, r); } } } return seg; } int main() { auto vs = tap(); int A[200005], B[200005], C[200005], D[200005]; int H = inf, W = inf, N = 0; for(auto&[a, b, c, d]: vs) { A[N] = a; B[N] = b; C[N] = c; D[N] = d; ++N; } A[N] = 0; B[N] = 0; C[N] = W; D[N] = 0; ++N; A[N] = 0; B[N] = 0; C[N] = 0; D[N] = H; ++N; A[N] = W; B[N] = 0; C[N] = W; D[N] = H; ++N; A[N] = 0; B[N] = H; C[N] = W; D[N] = H; ++N; W = Press(A, N, C, N); vector< Event > Events; for(int i = 0; i < N; i++) { if(A[i] == C[i]) { Events.push_back((Event) {B[i], i, CREATEY}); Events.push_back((Event) {D[i], i, DELETEY}); } else { Events.push_back((Event) {B[i], i, APPEARX}); } } sort(Events.begin(), Events.end()); set< int > pool; uf = new UnionFind(); tree = new SegmentTree(W); bit = new BinaryIndexedTree(W); pool.insert(0); decode[0] = uf->Make(); long long int sz = 0; for(int i = 0; i < Events.size(); i++) { const Event &e = Events[i]; const int &x = A[e.idx]; if(e.type == CREATEY) { int L = *--pool.lower_bound(x); decode[x] = Evaluate(x); decode[L] = Evaluate(L); decode[x] = decode[L]; pool.insert(x); bit->update(x, 1); } else if(e.type == DELETEY) { int L = *--pool.lower_bound(x); decode[x] = Evaluate(x); decode[L] = Evaluate(L); if(uf->Unite(decode[x], decode[L])) --sz; pool.erase(x); bit->update(x, -1); } else { int x2 = C[e.idx]; int RSQ = bit->query(x2) - bit->query(x - 1) - 1; if(RSQ > 0) { sz += RSQ; tree->AddF(x, *--pool.upper_bound(x2)); } } } cout << sz - 1 << "\n"; }