답안 #294991

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
294991 2020-09-09T11:42:47 Z 반딧불(#5812) 도로 개발 (JOI15_road_development) C++14
100 / 100
998 ms 41208 KB
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

struct disjointSet{
    int par[100002];
    void initialize(int n){
        for(int i=1; i<=n; i++) par[i] = i;
    }
    int find(int x){
        if(x==par[x]) return x;
        return par[x] = find(par[x]);
    }
    void merge(int x, int y){
        x = find(x), y = find(y);
        par[x] = y;
    }
} dsu;

struct Tree{
    int tree[400002], lazy[400002];
    void initialize(int i, int l, int r){
        if(l==r){
            tree[i] = 1, lazy[i] = 0;
            return;
        }
        int m = (l+r)>>1;
        initialize(i*2, l, m), initialize(i*2+1, m+1, r);
        tree[i] = tree[i*2] + tree[i*2+1], lazy[i] = 0;
    }
    void propagate(int i, int l, int r){
        if(!lazy[i]) return;
        tree[i] = 0;
        if(l!=r) lazy[i*2] = lazy[i*2+1] = 1;
        lazy[i] = 0;
    }
    void update(int i, int l, int r, int s, int e){
        propagate(i, l, r);
        if(r<s || e<l) return;
        if(s<=l && r<=e){
            lazy[i] = 1;
            propagate(i, l, r);
            return;
        }
        int m = (l+r)>>1;
        update(i*2, l, m, s, e);
        update(i*2+1, m+1, r, s, e);
        tree[i] = tree[i*2] + tree[i*2+1];
    }
    int getSum(int i, int l, int r, int s, int e){
        propagate(i, l, r);
        if(r<s || e<l) return 0;
        if(s<=l && r<=e) return tree[i];
        int m = (l+r)>>1;
        return getSum(i*2, l, m, s, e) + getSum(i*2+1, m+1, r, s, e);
    }
} tree;

int n, q;
int qt[300002], qa[300002], qb[300002];
vector<int> link[100002], child[100002];
int subTreeSize[100002];
int in[100002], out[100002], top[100002], p[100002], depth[100002], inCnt;
int LCADB[100002][20];

void input(){
    scanf("%d %d", &n, &q);
    for(int i=1; i<=q; i++){
        scanf("%d %d %d", &qt[i], &qa[i], &qb[i]);
    }
}

void makeTree(){
    dsu.initialize(n);
    for(int i=1; i<=q; i++){
        if(qt[i] == 2) continue;
        if(dsu.find(qa[i]) == dsu.find(qb[i])) continue;
        link[qa[i]].push_back(qb[i]);
        link[qb[i]].push_back(qa[i]);
        dsu.merge(qa[i], qb[i]);
    }
    for(int i=2; i<=n; i++){
        if(dsu.find(1) != dsu.find(i)){
            link[1].push_back(i), link[i].push_back(1);
            dsu.merge(1, i);
        }
    }
}

void dfs_sz(int x, int par=0){
    subTreeSize[x] = 1;
    p[x] = par;
    for(auto y: link[x]){
        if(y==par) continue;
        depth[y] = depth[x] + 1;
        child[x].push_back(y);
    }
    for(auto &y: child[x]){
        dfs_sz(y, x), subTreeSize[x] += subTreeSize[y];
        if(subTreeSize[y] > subTreeSize[child[x][0]]) swap(y, child[x][0]);
    }
}

void dfs_hld(int x){
    in[x] = ++inCnt;
    for(auto y: child[x]){
        if(y == child[x][0]) top[y] = top[x];
        else top[y] = y;
        dfs_hld(y);
    }
    out[x] = inCnt;
}

void heavyLightDecomposition(){
    depth[0] = -1; dfs_sz(1);
    top[1] = 1; dfs_hld(1);
}

void generateLCA(){
    for(int i=1; i<=n; i++) LCADB[i][0] = p[i];
    for(int d=1; d<20; d++) for(int i=1; i<=n; i++) LCADB[i][d] = LCADB[LCADB[i][d-1]][d-1];
}

int LCA(int x, int y){
    if(depth[x] > depth[y]) swap(x, y);
    for(int i=0; i<20; i++) if((1<<i) & (depth[y] - depth[x])) y = LCADB[y][i];
    if(x==y) return x;
    for(int i=19; i>=0; i--) if(LCADB[x][i] != LCADB[y][i]) x = LCADB[x][i], y = LCADB[y][i];
    return p[x];
}

void answerQueries(){
    dsu.initialize(n);
    tree.initialize(1, 1, n);
    for(int i=1; i<=q; i++){
        if(qt[i] == 1){
            int a = qa[i], b = qb[i];
            if(dsu.find(a) != dsu.find(b)){ /// needs new edge
                dsu.merge(a, b);
            }
            else{
                int c = LCA(a, b);
                while(depth[a] > depth[c]){
                    tree.update(1, 1, n, max(in[c]+1, in[top[a]]), in[a]);
                    a = p[top[a]];
                }
                while(depth[b] > depth[c]){
                    tree.update(1, 1, n, max(in[c]+1, in[top[b]]), in[b]);
                    b = p[top[b]];
                }
            }
        }
        else{
            int a = qa[i], b = qb[i];
            if(dsu.find(a) != dsu.find(b)){
                printf("-1\n");
            }
            else{
                int c = LCA(a, b), ret = 0;
                while(depth[a] > depth[c]){
                    ret += tree.getSum(1, 1, n, max(in[c]+1, in[top[a]]), in[a]);
                    a = p[top[a]];
                }
                while(depth[b] > depth[c]){
                    ret += tree.getSum(1, 1, n, max(in[c]+1, in[top[b]]), in[b]);
                    b = p[top[b]];
                }
                printf("%d\n", ret);
            }
        }
    }
}

int main(){
    input();
    makeTree();
    heavyLightDecomposition();
    generateLCA();
    answerQueries();
}

Compilation message

road_development.cpp: In function 'void input()':
road_development.cpp:69:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   69 |     scanf("%d %d", &n, &q);
      |     ~~~~~^~~~~~~~~~~~~~~~~
road_development.cpp:71:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   71 |         scanf("%d %d %d", &qt[i], &qa[i], &qb[i]);
      |         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 5248 KB Output is correct
2 Correct 8 ms 5376 KB Output is correct
3 Correct 7 ms 5376 KB Output is correct
4 Correct 6 ms 5376 KB Output is correct
5 Correct 7 ms 5376 KB Output is correct
6 Correct 6 ms 5376 KB Output is correct
7 Correct 7 ms 5376 KB Output is correct
8 Correct 6 ms 5376 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 511 ms 29472 KB Output is correct
2 Correct 998 ms 30300 KB Output is correct
3 Correct 672 ms 37808 KB Output is correct
4 Correct 653 ms 38712 KB Output is correct
5 Correct 640 ms 35804 KB Output is correct
6 Correct 631 ms 35832 KB Output is correct
7 Correct 779 ms 30456 KB Output is correct
8 Correct 637 ms 35396 KB Output is correct
9 Correct 782 ms 29944 KB Output is correct
10 Correct 609 ms 34480 KB Output is correct
11 Correct 595 ms 36984 KB Output is correct
12 Correct 465 ms 40824 KB Output is correct
13 Correct 515 ms 41208 KB Output is correct
14 Correct 608 ms 36600 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 423 ms 29680 KB Output is correct
2 Correct 705 ms 30584 KB Output is correct
3 Correct 657 ms 36344 KB Output is correct
4 Correct 593 ms 39416 KB Output is correct
5 Correct 394 ms 30328 KB Output is correct
6 Correct 659 ms 36216 KB Output is correct
7 Correct 310 ms 29424 KB Output is correct
8 Correct 592 ms 34936 KB Output is correct
9 Correct 470 ms 36472 KB Output is correct
10 Correct 597 ms 37240 KB Output is correct
11 Correct 378 ms 29040 KB Output is correct
12 Correct 634 ms 37608 KB Output is correct
13 Correct 594 ms 37880 KB Output is correct
14 Correct 494 ms 36984 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 264 ms 26736 KB Output is correct
2 Correct 552 ms 27640 KB Output is correct
3 Correct 448 ms 33016 KB Output is correct
4 Correct 407 ms 35704 KB Output is correct
5 Correct 891 ms 30044 KB Output is correct
6 Correct 621 ms 37368 KB Output is correct
7 Correct 126 ms 25080 KB Output is correct
8 Correct 137 ms 31352 KB Output is correct
9 Correct 158 ms 34808 KB Output is correct
10 Correct 187 ms 26732 KB Output is correct
11 Correct 552 ms 35576 KB Output is correct
12 Correct 606 ms 35320 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 5248 KB Output is correct
2 Correct 8 ms 5376 KB Output is correct
3 Correct 7 ms 5376 KB Output is correct
4 Correct 6 ms 5376 KB Output is correct
5 Correct 7 ms 5376 KB Output is correct
6 Correct 6 ms 5376 KB Output is correct
7 Correct 7 ms 5376 KB Output is correct
8 Correct 6 ms 5376 KB Output is correct
9 Correct 511 ms 29472 KB Output is correct
10 Correct 998 ms 30300 KB Output is correct
11 Correct 672 ms 37808 KB Output is correct
12 Correct 653 ms 38712 KB Output is correct
13 Correct 640 ms 35804 KB Output is correct
14 Correct 631 ms 35832 KB Output is correct
15 Correct 779 ms 30456 KB Output is correct
16 Correct 637 ms 35396 KB Output is correct
17 Correct 782 ms 29944 KB Output is correct
18 Correct 609 ms 34480 KB Output is correct
19 Correct 595 ms 36984 KB Output is correct
20 Correct 465 ms 40824 KB Output is correct
21 Correct 515 ms 41208 KB Output is correct
22 Correct 608 ms 36600 KB Output is correct
23 Correct 423 ms 29680 KB Output is correct
24 Correct 705 ms 30584 KB Output is correct
25 Correct 657 ms 36344 KB Output is correct
26 Correct 593 ms 39416 KB Output is correct
27 Correct 394 ms 30328 KB Output is correct
28 Correct 659 ms 36216 KB Output is correct
29 Correct 310 ms 29424 KB Output is correct
30 Correct 592 ms 34936 KB Output is correct
31 Correct 470 ms 36472 KB Output is correct
32 Correct 597 ms 37240 KB Output is correct
33 Correct 378 ms 29040 KB Output is correct
34 Correct 634 ms 37608 KB Output is correct
35 Correct 594 ms 37880 KB Output is correct
36 Correct 494 ms 36984 KB Output is correct
37 Correct 264 ms 26736 KB Output is correct
38 Correct 552 ms 27640 KB Output is correct
39 Correct 448 ms 33016 KB Output is correct
40 Correct 407 ms 35704 KB Output is correct
41 Correct 891 ms 30044 KB Output is correct
42 Correct 621 ms 37368 KB Output is correct
43 Correct 126 ms 25080 KB Output is correct
44 Correct 137 ms 31352 KB Output is correct
45 Correct 158 ms 34808 KB Output is correct
46 Correct 187 ms 26732 KB Output is correct
47 Correct 552 ms 35576 KB Output is correct
48 Correct 606 ms 35320 KB Output is correct
49 Correct 404 ms 29556 KB Output is correct
50 Correct 729 ms 30328 KB Output is correct
51 Correct 651 ms 37368 KB Output is correct
52 Correct 598 ms 40976 KB Output is correct
53 Correct 349 ms 28272 KB Output is correct
54 Correct 382 ms 29432 KB Output is correct
55 Correct 569 ms 36216 KB Output is correct
56 Correct 525 ms 38648 KB Output is correct
57 Correct 624 ms 35192 KB Output is correct
58 Correct 603 ms 35580 KB Output is correct
59 Correct 535 ms 36600 KB Output is correct
60 Correct 476 ms 37880 KB Output is correct
61 Correct 514 ms 37112 KB Output is correct