Submission #1113218

#TimeUsernameProblemLanguageResultExecution timeMemory
1113218Zero_OP절취선 (JOI14_ho_t5)C++14
100 / 100
974 ms77232 KiB
#include <bits/stdc++.h> using namespace std; struct fenwick_tree{ static const int offset = 1; vector<int> bit; fenwick_tree(int n) : bit(n + 1, 0) {} void update(int id, int val){ id += offset; for(; id < (int)bit.size(); id += id & (-id)) bit[id] += val; } int query(int id){ int sum = 0; id += offset; for(; id > 0; id -= id & (-id)) sum += bit[id]; return sum; } void update(int l, int r, int val){ update(l, val); update(r + 1, -val); } int query(int l, int r){ int cur = query(r) - query(l - 1); return cur; } }; struct disjoint_set{ vector<int> lab; int components; disjoint_set(int n) : components(n), lab(n, -1) {} int root(int u){ return lab[u] < 0 ? u : (lab[u] = root(lab[u])); } bool unite(int u, int v){ u = root(u); v = root(v); if(u == v) return false; if(lab[u] > lab[v]) swap(u, v); lab[u] += lab[v]; lab[v] = u; --components; return true; } int n_component(){ return components; } }; struct segment_tree_dsu{ using info = pair<int, int>; vector<set<info>> st; segment_tree_dsu(int n) : st(n << 2) {} void insert(int id, int l, int r, int pos, info v){ st[id].insert(v); if(l < r){ int mid = l + r >> 1; if(pos <= mid) insert(id << 1, l, mid, pos, v); else insert(id << 1 | 1, mid + 1, r, pos, v); } } void erase(int id, int l, int r, int pos, info v){ auto it = st[id].find(v); if(it != st[id].end()) st[id].erase(it); if(l < r){ int mid = l + r >> 1; if(pos <= mid) erase(id << 1, l, mid, pos, v); else erase(id << 1 | 1, mid + 1, r, pos, v); } } void join_segments(int id, int l, int r, int u, int v, int match, disjoint_set& dsu){ if(u <= l && r <= v){ while((int)st[id].size() > 1){ int p = st[id].begin() -> second; st[id].erase(st[id].begin()); dsu.unite(match, p); } if(!st[id].empty()) dsu.unite(match, st[id].begin() -> second); } else{ int mid = l + r >> 1; if(u <= mid) join_segments(id << 1, l, mid, u, v, match, dsu); if(mid < v) join_segments(id << 1 | 1, mid + 1, r, u, v, match, dsu); } } }; int main(){ ios_base::sync_with_stdio(0); cin.tie(0); if(fopen("task.inp", "r")){ freopen("task.inp", "r", stdin); freopen("task.out", "w", stdout); } int W, H, N; cin >> W >> H >> N; vector<tuple<int, int, int, int>> cuts; vector<int> x, y; for(int i = 0; i < N; ++i){ int a, b, c, d; cin >> a >> b >> c >> d; cuts.emplace_back(a, b, c, d); } cuts.emplace_back(0, 0, W, 0); cuts.emplace_back(0, 0, 0, H); cuts.emplace_back(W, 0, W, H); cuts.emplace_back(0, H, W, H); sort(cuts.begin(), cuts.end()); cuts.erase(unique(cuts.begin(), cuts.end()), cuts.end()); for(auto [a, b, c, d] : cuts){ x.emplace_back(a); x.emplace_back(c); y.emplace_back(b); y.emplace_back(d); } sort(x.begin(), x.end()); x.erase(unique(x.begin(), x.end()), x.end()); sort(y.begin(), y.end()); y.erase(unique(y.begin(), y.end()), y.end()); int nx = (int)x.size(), ny = (int)y.size(); vector<vector<pair<int, int>>> horizontal(ny), vertical(nx); for(auto& [a, b, c, d] : cuts){ a = lower_bound(x.begin(), x.end(), a) - x.begin(); c = lower_bound(x.begin(), x.end(), c) - x.begin(); b = lower_bound(y.begin(), y.end(), b) - y.begin(); d = lower_bound(y.begin(), y.end(), d) - y.begin(); if(a == c){ vertical[a].emplace_back(b, d); } else{ assert(b == d); horizontal[b].emplace_back(a, c); } } struct event{ int t, type, l, r, id; bool operator < (const event& o){ return make_pair(t, type) < make_pair(o.t, o.type); } }; vector<event> events; N = 0; for(int i = 0; i < nx; ++i){ auto& vec = vertical[i]; for(int j = 0; j < (int)vec.size(); ++j){ int l, r; tie(l, r) = vec[j]; while(j + 1 < (int)vec.size() && vec[j + 1].first <= r){ r = max(r, vec[j + 1].second); ++j; } events.push_back({i, 1, l, r, N++}); } } for(int i = 0; i < ny; ++i){ auto& vec = horizontal[i]; for(int j = 0; j < (int)vec.size(); ++j){ int l, r; tie(l, r) = vec[j]; while(j + 1 < (int)vec.size() && vec[j + 1].first <= r){ r = max(r, vec[j + 1].second); ++j; } events.push_back({l, 0, i, r, N}); events.push_back({r, 2, i, r, N}); ++N; } } sort(events.begin(), events.end()); long long n_intersection = 0; fenwick_tree ft(ny); disjoint_set dsu(N); segment_tree_dsu segtree(ny); for(auto [t, type, l, r, id] : events){ if(type == 0){ segtree.insert(1, 0, ny - 1, l, make_pair(r, id)); ft.update(l, +1); } else if(type == 1){ segtree.join_segments(1, 0, ny - 1, l, r, id, dsu); n_intersection += ft.query(l, r); } else{ segtree.erase(1, 0, ny - 1, l, make_pair(r, id)); ft.update(l, -1); } } long long V = n_intersection; long long E = N; long long C = dsu.n_component(); cout << V - E + C << '\n'; return 0; }

Compilation message (stderr)

2014_ho_t5.cpp: In constructor 'disjoint_set::disjoint_set(int)':
2014_ho_t5.cpp:35:9: warning: 'disjoint_set::components' will be initialized after [-Wreorder]
   35 |     int components;
      |         ^~~~~~~~~~
2014_ho_t5.cpp:34:17: warning:   'std::vector<int> disjoint_set::lab' [-Wreorder]
   34 |     vector<int> lab;
      |                 ^~~
2014_ho_t5.cpp:36:5: warning:   when initialized here [-Wreorder]
   36 |     disjoint_set(int n) : components(n), lab(n, -1) {}
      |     ^~~~~~~~~~~~
2014_ho_t5.cpp: In member function 'void segment_tree_dsu::insert(int, int, int, int, segment_tree_dsu::info)':
2014_ho_t5.cpp:66:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   66 |             int mid = l + r >> 1;
      |                       ~~^~~
2014_ho_t5.cpp: In member function 'void segment_tree_dsu::erase(int, int, int, int, segment_tree_dsu::info)':
2014_ho_t5.cpp:76:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   76 |             int mid = l + r >> 1;
      |                       ~~^~~
2014_ho_t5.cpp: In member function 'void segment_tree_dsu::join_segments(int, int, int, int, int, int, disjoint_set&)':
2014_ho_t5.cpp:92:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   92 |             int mid = l + r >> 1;
      |                       ~~^~~
2014_ho_t5.cpp: In function 'int main()':
2014_ho_t5.cpp:127:14: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  127 |     for(auto [a, b, c, d] : cuts){
      |              ^
2014_ho_t5.cpp:143:15: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  143 |     for(auto& [a, b, c, d] : cuts){
      |               ^
2014_ho_t5.cpp:202:14: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  202 |     for(auto [t, type, l, r, id] : events){
      |              ^
2014_ho_t5.cpp:104:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  104 |         freopen("task.inp", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
2014_ho_t5.cpp:105:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  105 |         freopen("task.out", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...