結果
問題 | No.766 金魚すくい |
ユーザー | ei1333333 |
提出日時 | 2018-10-30 23:41:03 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 2,007 bytes |
コンパイル時間 | 2,140 ms |
コンパイル使用メモリ | 206,072 KB |
実行使用メモリ | 7,960 KB |
最終ジャッジ日時 | 2024-06-06 23:53:41 |
合計ジャッジ時間 | 9,307 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | WA | - |
testcase_01 | WA | - |
testcase_02 | WA | - |
testcase_03 | RE | - |
testcase_04 | WA | - |
testcase_05 | RE | - |
testcase_06 | RE | - |
testcase_07 | RE | - |
testcase_08 | RE | - |
testcase_09 | RE | - |
testcase_10 | RE | - |
testcase_11 | RE | - |
testcase_12 | RE | - |
testcase_13 | RE | - |
testcase_14 | RE | - |
testcase_15 | RE | - |
testcase_16 | RE | - |
testcase_17 | RE | - |
testcase_18 | RE | - |
testcase_19 | RE | - |
testcase_20 | RE | - |
testcase_21 | RE | - |
testcase_22 | RE | - |
testcase_23 | RE | - |
testcase_24 | RE | - |
testcase_25 | RE | - |
testcase_26 | RE | - |
testcase_27 | RE | - |
testcase_28 | RE | - |
testcase_29 | RE | - |
testcase_30 | RE | - |
testcase_31 | RE | - |
testcase_32 | RE | - |
testcase_33 | RE | - |
testcase_34 | RE | - |
testcase_35 | WA | - |
testcase_36 | WA | - |
testcase_37 | RE | - |
testcase_38 | RE | - |
testcase_39 | RE | - |
testcase_40 | RE | - |
testcase_41 | WA | - |
testcase_42 | WA | - |
testcase_43 | WA | - |
testcase_44 | AC | 19 ms
7,220 KB |
ソースコード
#include <bits/stdc++.h> using namespace std; using int64 = long long; const int INF = 1 << 30; struct UnionFind { vector< int > data; UnionFind(int sz) { data.assign(sz, -1); } bool unite(int x, int y) { x = find(x), y = find(y); if(x == y) return (false); if(data[x] > data[y]) swap(x, y); data[x] += data[y]; data[y] = x; return (true); } int find(int k) { if(data[k] < 0) return (k); return (data[k] = find(data[k])); } int size(int k) { return (-data[find(k)]); } }; int main() { int N, A[100000], B[100000]; int64 in[100001] = {}, out[100001] = {}; UnionFind uf(100001); cin >> N; int low = INF; for(int i = 0; i < N; i++) { cin >> A[i] >> B[i]; out[A[i]]++; in[B[i]]++; low = min(low, B[i]); uf.unite(A[i], B[i]); } int64 up[100002] = {}, down[100002] = {}; //i-1 ↔ i for(int i = 100000; i > low; i--) { up[i] = max((up[i + 1] + out[i]) - (down[i + 1] + in[i]), 0LL); down[i] = max((down[i + 1] + in[i]) - (up[i + 1] + out[i]), 0LL); if(up[i] > 0 || down[i] > 0) uf.unite(i - 1, i); } for(int i = 100000; i > low; i--) { if(uf.find(i) != uf.find(i - 1)) { uf.unite(i, i - 1); assert(up[i] == 0 && down[i] == 0); up[i] = down[i] = 1; } } auto check = [&](int left) { for(int i = left; i <= 100000; i++) up[i]--; UnionFind uf2(100001); for(int i = 0; i < N; i++) uf2.unite(A[i], B[i]); for(int i = 100000; i > low; i--) { if(up[i] > 0 || down[i] > 0) uf2.unite(i - 1, i); } int par = uf2.find(100000); bool f = true; for(int i = 0; i < N; i++) f &= uf2.find(A[i]) == par; for(int i = left; i <= 100000; i++) up[i]++; return f; }; int ok = 100001, ng = low; while(ok - ng > 1) { int mid = (ok + ng) / 2; if(check(mid)) ok = mid; else ng = mid; } int64 all = 0; for(int i = ok; i <= 100000; i++) up[i]--; for(int i = 0; i <= 100000; i++) all += up[i]; cout << all << endl; }