답안 #868635

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
868635 2023-11-01T04:00:51 Z hgmhc 절취선 (JOI14_ho_t5) C++17
100 / 100
317 ms 40320 KB
#include <bits/stdc++.h>
#define rep(i,a,b) for (auto i = (a); i <= (b); ++i)
using namespace std;
    
const int M = 2e5+10;
int w, h, n;
vector<pair<int,int>> ver[M], hor[M];
    
namespace sub4 {
    
    template <const int N>
    struct fenwick {
        int t[N+1]{};
        void add(int k, int x) {
            for (++k; k <= N; k += k&-k) t[k] += x;
        }
        int sum(int a, int b) {
            int r = 0;
            for (; a >= 1; a -= a&-a) r -= t[a];
            for (++b; b >= 1; b -= b&-b) r += t[b];
            return r;
        }
    };
    
    fenwick<M> ds;
    
    int64_t sweep_v() {
        // 꼭짓점 말고 교차점만 카운트
        vector<int> in[M], out[M];
        rep(i,0,M-1) {
            for (auto [x1,x2] : hor[i]) {
                if (x1 > x2) swap(x1,x2);
                in[x1].push_back(i);
                out[x2].push_back(i);
            }
        }
        int64_t res = 0;
        rep(i,0,M-1) {
            for (auto y : in[i]) ds.add(y,+1);
            for (auto [y1,y2] : ver[i]) {
                if (y1 > y2) swap(y1,y2);
                res += ds.sum(y1,y2);
            }
            for (auto y : out[i]) ds.add(y,-1);
        }
        return res;
    }
    
    int64_t sweep_e() {
        // 선분마다 꼭짓점은 무시하고 교차점-1로 카운트
        vector<int> in[M], out[M];
        rep(i,0,M-1) {
            for (auto [x1,x2] : hor[i]) {
                if (x1 > x2) swap(x1,x2);
                in[x1].push_back(i);
                out[x2].push_back(i);
            }
        }
        int64_t res = 0;
        rep(i,0,M-1) {
            for (auto y : in[i]) ds.add(y,+1);
            for (auto [y1,y2] : ver[i]) {
                if (y1 > y2) swap(y1,y2);
                res += ds.sum(y1,y2)-1;
            }
            for (auto y : out[i]) ds.add(y,-1);
        }
        return res;
    }
    
    int64_t get_v() {
        int64_t res = sweep_v();
        swap(ver,hor);
        res += sweep_v();
        return res;
    }
    
    int64_t get_e() {
        int64_t res = sweep_e();
        swap(ver,hor);
        res += sweep_e();
        return res;
    }
    
}

namespace sub5 {

    int p[2*M], cnt=0;
    int find(int x) {
        if (x == p[x]) return x;
        return p[x] = find(p[x]);
    }
    int merge(int a, int b) {
        int x=a, y=b;
        if (a == 0) return b;
        if (b == 0) return a;
        a = find(a), b = find(b);
        if (a == b) return a;
        // cerr << x << ' ' << y << endl;
        cnt++;
        p[b] = a;
        return a;
    }

    // [a,b]에 뭐라도 남아있다면, 양 자식에 레이지 밀어서 합치기
    // [a,b]에 아무것도 없으면, 레이지를 보존할 이유 없음

    template <const int N=1<<18>
    struct segtree {
        int t[2*N]{}, sum[2*N]{};
        segtree(){ iota(p,p+2*M,0); }
        void prop(int k) {
            if (k < N) {
                if (sum[2*k]) t[2*k] = merge(t[2*k],t[k]);
                if (sum[2*k+1]) t[2*k+1] = merge(t[2*k+1],t[k]);
            }
            t[k]=0;
        }
        void update(int i, int c, int d, int k=1, int s=0, int e=N-1) {
            prop(k);
            if (s == i and i == e) { t[k] = c, sum[k]+=d; return; }
            int m = (s+e)/2;
            if (i <= m) update(i,c,d,2*k,s,m);
            else update(i,c,d,2*k+1,m+1,e);
            sum[k]+=d;
        }
        void join(int a, int b, int c) {
            for (a += N, b += N; a <= b; ++a /= 2, --b /= 2) {
                if (a&1) {
                    if (sum[a]) merge(c,t[a]);
                    t[a]=c;
                }
                if (~b&1) {
                    if (sum[b]) merge(c,t[b]);
                    t[b]=c;
                }
            }
        }
    };
    
    segtree<> ds;
    
    int64_t get_c() {
        vector<int> in[M], out[M];
        rep(i,0,M-1) {
            for (auto [x1,x2] : hor[i]) {
                if (x1 > x2) swap(x1,x2);
                in[x1].push_back(i);
                out[x2].push_back(i);
            }
        }
        int clr = 0;
        rep(i,0,M-1) {
            for (auto y : in[i]) ds.update(y,++clr,+1);
            for (auto [y1,y2] : ver[i]) {
                if (y1 > y2) swap(y1,y2);
                ds.join(y1,y2,++clr);
            }
            for (auto y : out[i]) ds.update(y,0,-1);
            // cerr << clr << ' ' << cnt << endl;
        }
        return clr-cnt;
    }
}

void solve() {
    int64_t v = sub4::get_v() / 2LL;
    int64_t e = sub4::get_e();
    int64_t f = sub5::get_c()-v+e;
    // fprintf(stderr,"v=%lld, e=%lld, f=%lld",v,e,f);
    cout << f;
}

int main() {
    cin.tie(0)->sync_with_stdio(0);
    cin >> w >> h >> n;
    vector<array<int,4>> segments(n);
    vector<int> xs, ys;
    xs.push_back(0), xs.push_back(w);
    ys.push_back(0), ys.push_back(h);
    for (auto &[a,b,c,d] : segments) {
        cin >> a >> b >> c >> d;
        xs.push_back(a), xs.push_back(c);
        ys.push_back(b), ys.push_back(d);
    }
    segments.push_back({w,0,0,0});
    segments.push_back({w,h,0,h});
    segments.push_back({w,0,w,h});
    segments.push_back({0,h,0,0});
    sort(begin(xs),end(xs)), xs.erase(unique(begin(xs),end(xs)),end(xs));
    sort(begin(ys),end(ys)), ys.erase(unique(begin(ys),end(ys)),end(ys));
    for (auto &[a,b,c,d] : segments) {
        a = lower_bound(begin(xs),end(xs),a)-begin(xs);
        b = lower_bound(begin(ys),end(ys),b)-begin(ys);
        c = lower_bound(begin(xs),end(xs),c)-begin(xs);
        d = lower_bound(begin(ys),end(ys),d)-begin(ys);
        // cerr << a << ' ' << b << ' ' << c << ' ' << d << endl;
        if (a == c) {
            ver[a].push_back({b,d});
        } else {
            hor[b].push_back({a,c});
        }
    }
    solve();
}

Compilation message

2014_ho_t5.cpp: In function 'int sub5::merge(int, int)':
2014_ho_t5.cpp:95:13: warning: unused variable 'x' [-Wunused-variable]
   95 |         int x=a, y=b;
      |             ^
2014_ho_t5.cpp:95:18: warning: unused variable 'y' [-Wunused-variable]
   95 |         int x=a, y=b;
      |                  ^
# 결과 실행 시간 메모리 Grader output
1 Correct 18 ms 25692 KB Output is correct
2 Correct 19 ms 25436 KB Output is correct
3 Correct 21 ms 25520 KB Output is correct
4 Correct 19 ms 25708 KB Output is correct
5 Correct 20 ms 25696 KB Output is correct
6 Correct 19 ms 25692 KB Output is correct
7 Correct 20 ms 25708 KB Output is correct
8 Correct 23 ms 25688 KB Output is correct
9 Correct 21 ms 25692 KB Output is correct
10 Correct 22 ms 25692 KB Output is correct
11 Correct 21 ms 25780 KB Output is correct
12 Correct 20 ms 25528 KB Output is correct
13 Correct 20 ms 25692 KB Output is correct
14 Correct 20 ms 25788 KB Output is correct
15 Correct 21 ms 25792 KB Output is correct
16 Correct 19 ms 25692 KB Output is correct
17 Correct 19 ms 25692 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 18 ms 25692 KB Output is correct
2 Correct 19 ms 25436 KB Output is correct
3 Correct 21 ms 25520 KB Output is correct
4 Correct 19 ms 25708 KB Output is correct
5 Correct 20 ms 25696 KB Output is correct
6 Correct 19 ms 25692 KB Output is correct
7 Correct 20 ms 25708 KB Output is correct
8 Correct 23 ms 25688 KB Output is correct
9 Correct 21 ms 25692 KB Output is correct
10 Correct 22 ms 25692 KB Output is correct
11 Correct 21 ms 25780 KB Output is correct
12 Correct 20 ms 25528 KB Output is correct
13 Correct 20 ms 25692 KB Output is correct
14 Correct 20 ms 25788 KB Output is correct
15 Correct 21 ms 25792 KB Output is correct
16 Correct 19 ms 25692 KB Output is correct
17 Correct 19 ms 25692 KB Output is correct
18 Correct 20 ms 25692 KB Output is correct
19 Correct 20 ms 25704 KB Output is correct
20 Correct 20 ms 25944 KB Output is correct
21 Correct 22 ms 25844 KB Output is correct
22 Correct 22 ms 25688 KB Output is correct
23 Correct 21 ms 25768 KB Output is correct
24 Correct 21 ms 25692 KB Output is correct
25 Correct 21 ms 26032 KB Output is correct
26 Correct 21 ms 25620 KB Output is correct
27 Correct 21 ms 25720 KB Output is correct
28 Correct 23 ms 25812 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 21 ms 25692 KB Output is correct
2 Correct 20 ms 25692 KB Output is correct
3 Correct 21 ms 25692 KB Output is correct
4 Correct 21 ms 25608 KB Output is correct
5 Correct 41 ms 26980 KB Output is correct
6 Correct 132 ms 32180 KB Output is correct
7 Correct 266 ms 39436 KB Output is correct
8 Correct 269 ms 38744 KB Output is correct
9 Correct 253 ms 39836 KB Output is correct
10 Correct 254 ms 40320 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 20 ms 25672 KB Output is correct
2 Correct 23 ms 25692 KB Output is correct
3 Correct 40 ms 26812 KB Output is correct
4 Correct 20 ms 25692 KB Output is correct
5 Correct 21 ms 25692 KB Output is correct
6 Correct 311 ms 37544 KB Output is correct
7 Correct 28 ms 26552 KB Output is correct
8 Correct 122 ms 35736 KB Output is correct
9 Correct 137 ms 35868 KB Output is correct
10 Correct 140 ms 34444 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 18 ms 25692 KB Output is correct
2 Correct 19 ms 25436 KB Output is correct
3 Correct 21 ms 25520 KB Output is correct
4 Correct 19 ms 25708 KB Output is correct
5 Correct 20 ms 25696 KB Output is correct
6 Correct 19 ms 25692 KB Output is correct
7 Correct 20 ms 25708 KB Output is correct
8 Correct 23 ms 25688 KB Output is correct
9 Correct 21 ms 25692 KB Output is correct
10 Correct 22 ms 25692 KB Output is correct
11 Correct 21 ms 25780 KB Output is correct
12 Correct 20 ms 25528 KB Output is correct
13 Correct 20 ms 25692 KB Output is correct
14 Correct 20 ms 25788 KB Output is correct
15 Correct 21 ms 25792 KB Output is correct
16 Correct 19 ms 25692 KB Output is correct
17 Correct 19 ms 25692 KB Output is correct
18 Correct 20 ms 25692 KB Output is correct
19 Correct 20 ms 25704 KB Output is correct
20 Correct 20 ms 25944 KB Output is correct
21 Correct 22 ms 25844 KB Output is correct
22 Correct 22 ms 25688 KB Output is correct
23 Correct 21 ms 25768 KB Output is correct
24 Correct 21 ms 25692 KB Output is correct
25 Correct 21 ms 26032 KB Output is correct
26 Correct 21 ms 25620 KB Output is correct
27 Correct 21 ms 25720 KB Output is correct
28 Correct 23 ms 25812 KB Output is correct
29 Correct 21 ms 25692 KB Output is correct
30 Correct 20 ms 25692 KB Output is correct
31 Correct 21 ms 25692 KB Output is correct
32 Correct 21 ms 25608 KB Output is correct
33 Correct 41 ms 26980 KB Output is correct
34 Correct 132 ms 32180 KB Output is correct
35 Correct 266 ms 39436 KB Output is correct
36 Correct 269 ms 38744 KB Output is correct
37 Correct 253 ms 39836 KB Output is correct
38 Correct 254 ms 40320 KB Output is correct
39 Correct 20 ms 25672 KB Output is correct
40 Correct 23 ms 25692 KB Output is correct
41 Correct 40 ms 26812 KB Output is correct
42 Correct 20 ms 25692 KB Output is correct
43 Correct 21 ms 25692 KB Output is correct
44 Correct 311 ms 37544 KB Output is correct
45 Correct 28 ms 26552 KB Output is correct
46 Correct 122 ms 35736 KB Output is correct
47 Correct 137 ms 35868 KB Output is correct
48 Correct 140 ms 34444 KB Output is correct
49 Correct 21 ms 25788 KB Output is correct
50 Correct 21 ms 25644 KB Output is correct
51 Correct 22 ms 25808 KB Output is correct
52 Correct 143 ms 32324 KB Output is correct
53 Correct 130 ms 32440 KB Output is correct
54 Correct 140 ms 32180 KB Output is correct
55 Correct 301 ms 38812 KB Output is correct
56 Correct 272 ms 39616 KB Output is correct
57 Correct 296 ms 38964 KB Output is correct
58 Correct 317 ms 38968 KB Output is correct
59 Correct 140 ms 36000 KB Output is correct
60 Correct 140 ms 35860 KB Output is correct
61 Correct 151 ms 37132 KB Output is correct
62 Correct 166 ms 36512 KB Output is correct
63 Correct 297 ms 38956 KB Output is correct
64 Correct 271 ms 39076 KB Output is correct
65 Correct 295 ms 39736 KB Output is correct
66 Correct 310 ms 40092 KB Output is correct
67 Correct 290 ms 38720 KB Output is correct
68 Correct 290 ms 38812 KB Output is correct
69 Correct 282 ms 38816 KB Output is correct
70 Correct 277 ms 38732 KB Output is correct
71 Correct 140 ms 36252 KB Output is correct
72 Correct 179 ms 35532 KB Output is correct