답안 #293073

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
293073 2020-09-07T15:58:43 Z 반딧불(#5810) 서류 전달 (ROI16_sending) C++17
53 / 100
966 ms 107848 KB
#include <bits/stdc++.h>
#define LIM 20

using namespace std;

typedef long long ll;
typedef pair<int, int> pi;

struct Path{
    int x, y, idx;
    Path(){}
    Path(int x, int y, int idx): x(x), y(y), idx(idx){}

    bool operator<(const Path &r)const{
        if(x != r.x) return x < r.x;
        if(y != r.x) return y < r.y;
        return idx < r.idx;
    }
};

int n, k;
int par[800002];
vector<int> link[800002];
vector<int> centroidChild[800002];
int subTreeSize[800002];
bool centroidUsed[800002];
int centroidRoot;

int ans, ansX=1, ansY=2;

int getSubTreeSize(int x, int par){
    subTreeSize[x] = 1;
    for(auto &y: link[x]){
        if(y == par || centroidUsed[y]) continue;
        subTreeSize[x] += getSubTreeSize(y, x);
    }
    return subTreeSize[x];
}
int findCentroid(int x){
    int par = 0;
    int treeSize = getSubTreeSize(x, 0);
    while(1){
        int maxTreeSize = 0, maxTreeIdx = -1;
        for(auto &y: link[x]){
            if(centroidUsed[y] || y == par) continue;
            if(subTreeSize[y] > maxTreeSize) maxTreeSize = subTreeSize[y], maxTreeIdx = y;
        }
        if(maxTreeSize <= treeSize / 2){
            break;
        }
        par = x;
        x = maxTreeIdx;
    }
    centroidUsed[x] = 1;
    for(auto &y: link[x]){
        if(centroidUsed[y]) continue;
        int tmp = findCentroid(y);
        centroidChild[x].push_back(tmp);
    }
    return x;
}

int group[800002];
int in[800002], inCnt, depth[800002], inIdx[800002];
vector<pair<int, int> > oppVec[400002];
set<pair<int, int> > sets[400002];
int sparse[800002][LIM];
int cover[800002];

void dfsGroup(int x, int groupNum, int p = 0){
    group[x] = groupNum;
    in[x] = ++inCnt, inIdx[in[x]] = x;
    vector<pair<int, int> >().swap(oppVec[x]);
    sets[x].clear();
    for(auto &y: link[x]){
        if(centroidUsed[y] || y==p) continue;
        depth[y] = depth[x]+1;
        dfsGroup(y, groupNum, x);

        inIdx[++inCnt] = x;
    }
}

inline int LCAdepth(int x, int y){
    x = in[x], y = in[y];
    if(x>y) swap(x, y);
    int d = cover[y-x];
    return min(sparse[x][d], sparse[y-(1<<d)+1][d]);
}

inline void put(int x, pair<int, int> p){
    auto it = sets[x].lower_bound(p);
    if(it != sets[x].end()){
        int tmp = depth[x] + LCAdepth(p.first, it->first);
        if(tmp > ans) ans = tmp, ansX = p.second, ansY = it->second;
    }
    if(it != sets[x].begin()){
        it = prev(it);
        int tmp = depth[x] + LCAdepth(p.first, it->first);
        if(tmp > ans) ans = tmp, ansX = p.second, ansY = it->second;
    }
    sets[x].insert(p);
}

void dfsCalc(int x, int p = 0){
    int maxVal = -1, max_loc = -1;
    for(auto &y: link[x]){
        if(centroidUsed[y] || y==p) continue;
        dfsCalc(y, x);
        if(maxVal < (int)sets[y].size()) maxVal = sets[y].size(), max_loc = y;
    }

    sets[x].swap(sets[max_loc]);
    for(auto &y: link[x]){
        if(centroidUsed[y] || y==p || y==max_loc) continue;
        for(auto p: sets[y]) put(x, p);
        sets[y].clear();
    }
    for(auto p: oppVec[x]){
        put(x, p);
    }
}

void findAnswer(int c, vector<Path> &ust){
    vector<int> nearChild;
    vector<vector<pi> > groupVec;
    vector<vector<Path> > propVec;
    int s;

    for(auto &y: link[c]){
        if(centroidUsed[y]) continue;
        depth[y] = 1; nearChild.push_back(y);
    }
    centroidUsed[c] = 1;
    if(nearChild.empty() || ust.size() <= 1) return;
    s = (int)nearChild.size();
    groupVec.resize(s), propVec.resize(s);

    inCnt = depth[c] = 0;
    for(int i=0; i<s; i++){
        dfsGroup(nearChild[i], i);
        inIdx[++inCnt] = c;
    }
    for(int i=inCnt; i>=1; i--){
        sparse[i][0] = depth[inIdx[i]];
        for(int j=1; i+(1<<j)<=inCnt; j++){
            sparse[i][j] = min(sparse[i][j-1], sparse[i+(1<<(j-1))][j-1]);
        }
    }

    for(auto p: ust){
        if(p.x != c && p.y != c && group[p.x] == group[p.y]){
            propVec[group[p.x]].push_back(Path(p.x, p.y, p.idx));
            continue;
        }
        if(p.x != c) groupVec[group[p.x]].push_back({in[p.x], p.idx});
        if(p.y != c) groupVec[group[p.y]].push_back({in[p.y], p.idx});

        if(p.x != c && p.y != c){
            oppVec[p.x].push_back({p.y, p.idx});
            oppVec[p.y].push_back({p.x, p.idx});
        }
    }

    for(int i=0; i<s; i++){ /// check when common subtree is only one
        sort(groupVec[i].begin(), groupVec[i].end());
        for(int j=0; j<(int)groupVec[i].size()-1; j++){
            int tmp = LCAdepth(inIdx[groupVec[i][j].first], inIdx[groupVec[i][j+1].first]);
            if(ans < tmp){
                ans = tmp, ansX = groupVec[i][j].second, ansY = groupVec[i][j+1].second;
            }
        }

        for(int j=0; j<(int)groupVec[i].size(); j++){
            if(j && groupVec[i][j].first == groupVec[i][j-1].first) continue;
            int tmp1 = nearChild[i], tmp2 = inIdx[groupVec[i][j].first];
            if(tmp1 != tmp2) propVec[i].push_back(Path(tmp1, tmp2, groupVec[i][j].second));
        }
    }

    /// check when common subtree is two
    for(int i=0; i<s; i++){
        dfsCalc(nearChild[i]);
    }

    vector<int>().swap(nearChild);
    for(auto &x: groupVec) vector<pi>().swap(x);
    vector<vector<pi> >().swap(groupVec);

    /// propagate to childs
    for(auto &chd: centroidChild[c]){
        findAnswer(chd, propVec[group[chd]]);
        vector<Path>().swap(propVec[group[chd]]);
    }
}


int main(){
    for(int i=1; i<=600000; i++) cover[i] = cover[(i-1)/2]+1;

    scanf("%d %d", &n, &k);

    for(int i=2; i<=n; i++){
        scanf("%d", &par[i]);
        link[i].push_back(par[i]);
        link[par[i]].push_back(i);
    }
    centroidRoot = findCentroid(1);
    memset(centroidUsed, 0, sizeof(centroidUsed));

    vector<Path> st;
    for(int i=1; i<=k; i++){
        int x, y;
        scanf("%d %d", &x, &y);
        st.push_back(Path(x, y, i));
    }

    findAnswer(centroidRoot, st);
    printf("%d\n%d %d", ans, ansX, ansY);
}

Compilation message

sending.cpp: In function 'int main()':
sending.cpp:201:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  201 |     scanf("%d %d", &n, &k);
      |     ~~~~~^~~~~~~~~~~~~~~~~
sending.cpp:204:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  204 |         scanf("%d", &par[i]);
      |         ~~~~~^~~~~~~~~~~~~~~
sending.cpp:214:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  214 |         scanf("%d %d", &x, &y);
      |         ~~~~~^~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 47 ms 69248 KB Output is correct
2 Correct 46 ms 69248 KB Output is correct
3 Correct 51 ms 69240 KB Output is correct
4 Correct 49 ms 69264 KB Output is correct
5 Correct 49 ms 69240 KB Output is correct
6 Correct 48 ms 69368 KB Output is correct
7 Correct 49 ms 69248 KB Output is correct
8 Correct 47 ms 69368 KB Output is correct
9 Correct 47 ms 69332 KB Output is correct
10 Correct 47 ms 69240 KB Output is correct
11 Correct 46 ms 69240 KB Output is correct
12 Correct 47 ms 69244 KB Output is correct
13 Correct 51 ms 69248 KB Output is correct
14 Correct 48 ms 69240 KB Output is correct
15 Correct 47 ms 69240 KB Output is correct
16 Correct 50 ms 69240 KB Output is correct
17 Correct 54 ms 69344 KB Output is correct
18 Correct 51 ms 69240 KB Output is correct
19 Correct 47 ms 69240 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 47 ms 69248 KB Output is correct
2 Correct 46 ms 69248 KB Output is correct
3 Correct 51 ms 69240 KB Output is correct
4 Correct 49 ms 69264 KB Output is correct
5 Correct 49 ms 69240 KB Output is correct
6 Correct 48 ms 69368 KB Output is correct
7 Correct 49 ms 69248 KB Output is correct
8 Correct 47 ms 69368 KB Output is correct
9 Correct 47 ms 69332 KB Output is correct
10 Correct 47 ms 69240 KB Output is correct
11 Correct 46 ms 69240 KB Output is correct
12 Correct 47 ms 69244 KB Output is correct
13 Correct 51 ms 69248 KB Output is correct
14 Correct 48 ms 69240 KB Output is correct
15 Correct 47 ms 69240 KB Output is correct
16 Correct 50 ms 69240 KB Output is correct
17 Correct 54 ms 69344 KB Output is correct
18 Correct 51 ms 69240 KB Output is correct
19 Correct 47 ms 69240 KB Output is correct
20 Correct 60 ms 70392 KB Output is correct
21 Correct 57 ms 70400 KB Output is correct
22 Correct 63 ms 70648 KB Output is correct
23 Correct 75 ms 70648 KB Output is correct
24 Correct 58 ms 70564 KB Output is correct
25 Correct 53 ms 70520 KB Output is correct
26 Correct 67 ms 70648 KB Output is correct
27 Correct 58 ms 70264 KB Output is correct
28 Correct 53 ms 70392 KB Output is correct
29 Correct 60 ms 70520 KB Output is correct
30 Correct 57 ms 70648 KB Output is correct
31 Correct 55 ms 70648 KB Output is correct
32 Correct 68 ms 70648 KB Output is correct
33 Correct 58 ms 70648 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 47 ms 69248 KB Output is correct
2 Correct 46 ms 69248 KB Output is correct
3 Correct 51 ms 69240 KB Output is correct
4 Correct 49 ms 69264 KB Output is correct
5 Correct 49 ms 69240 KB Output is correct
6 Correct 48 ms 69368 KB Output is correct
7 Correct 49 ms 69248 KB Output is correct
8 Correct 47 ms 69368 KB Output is correct
9 Correct 47 ms 69332 KB Output is correct
10 Correct 47 ms 69240 KB Output is correct
11 Correct 46 ms 69240 KB Output is correct
12 Correct 47 ms 69244 KB Output is correct
13 Correct 51 ms 69248 KB Output is correct
14 Correct 48 ms 69240 KB Output is correct
15 Correct 47 ms 69240 KB Output is correct
16 Correct 50 ms 69240 KB Output is correct
17 Correct 54 ms 69344 KB Output is correct
18 Correct 51 ms 69240 KB Output is correct
19 Correct 47 ms 69240 KB Output is correct
20 Correct 60 ms 70392 KB Output is correct
21 Correct 57 ms 70400 KB Output is correct
22 Correct 63 ms 70648 KB Output is correct
23 Correct 75 ms 70648 KB Output is correct
24 Correct 58 ms 70564 KB Output is correct
25 Correct 53 ms 70520 KB Output is correct
26 Correct 67 ms 70648 KB Output is correct
27 Correct 58 ms 70264 KB Output is correct
28 Correct 53 ms 70392 KB Output is correct
29 Correct 60 ms 70520 KB Output is correct
30 Correct 57 ms 70648 KB Output is correct
31 Correct 55 ms 70648 KB Output is correct
32 Correct 68 ms 70648 KB Output is correct
33 Correct 58 ms 70648 KB Output is correct
34 Correct 434 ms 92636 KB Output is correct
35 Incorrect 480 ms 92792 KB Output isn't correct
36 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 47 ms 69248 KB Output is correct
2 Correct 46 ms 69248 KB Output is correct
3 Correct 51 ms 69240 KB Output is correct
4 Correct 49 ms 69264 KB Output is correct
5 Correct 49 ms 69240 KB Output is correct
6 Correct 48 ms 69368 KB Output is correct
7 Correct 49 ms 69248 KB Output is correct
8 Correct 47 ms 69368 KB Output is correct
9 Correct 47 ms 69332 KB Output is correct
10 Correct 47 ms 69240 KB Output is correct
11 Correct 46 ms 69240 KB Output is correct
12 Correct 47 ms 69244 KB Output is correct
13 Correct 51 ms 69248 KB Output is correct
14 Correct 48 ms 69240 KB Output is correct
15 Correct 47 ms 69240 KB Output is correct
16 Correct 50 ms 69240 KB Output is correct
17 Correct 54 ms 69344 KB Output is correct
18 Correct 51 ms 69240 KB Output is correct
19 Correct 47 ms 69240 KB Output is correct
20 Correct 60 ms 70392 KB Output is correct
21 Correct 57 ms 70400 KB Output is correct
22 Correct 63 ms 70648 KB Output is correct
23 Correct 75 ms 70648 KB Output is correct
24 Correct 58 ms 70564 KB Output is correct
25 Correct 53 ms 70520 KB Output is correct
26 Correct 67 ms 70648 KB Output is correct
27 Correct 58 ms 70264 KB Output is correct
28 Correct 53 ms 70392 KB Output is correct
29 Correct 60 ms 70520 KB Output is correct
30 Correct 57 ms 70648 KB Output is correct
31 Correct 55 ms 70648 KB Output is correct
32 Correct 68 ms 70648 KB Output is correct
33 Correct 58 ms 70648 KB Output is correct
34 Correct 434 ms 92636 KB Output is correct
35 Incorrect 480 ms 92792 KB Output isn't correct
36 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 467 ms 97884 KB Output is correct
2 Correct 966 ms 103920 KB Output is correct
3 Incorrect 860 ms 103748 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 592 ms 97508 KB Output is correct
2 Correct 717 ms 97552 KB Output is correct
3 Correct 744 ms 106820 KB Output is correct
4 Correct 708 ms 106480 KB Output is correct
5 Correct 688 ms 102164 KB Output is correct
6 Correct 138 ms 98540 KB Output is correct
7 Correct 738 ms 106848 KB Output is correct
8 Correct 191 ms 95552 KB Output is correct
9 Correct 331 ms 94576 KB Output is correct
10 Correct 182 ms 106992 KB Output is correct
11 Correct 454 ms 107848 KB Output is correct
12 Correct 435 ms 107480 KB Output is correct
13 Correct 770 ms 107244 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 47 ms 69248 KB Output is correct
2 Correct 46 ms 69248 KB Output is correct
3 Correct 51 ms 69240 KB Output is correct
4 Correct 49 ms 69264 KB Output is correct
5 Correct 49 ms 69240 KB Output is correct
6 Correct 48 ms 69368 KB Output is correct
7 Correct 49 ms 69248 KB Output is correct
8 Correct 47 ms 69368 KB Output is correct
9 Correct 47 ms 69332 KB Output is correct
10 Correct 47 ms 69240 KB Output is correct
11 Correct 46 ms 69240 KB Output is correct
12 Correct 47 ms 69244 KB Output is correct
13 Correct 51 ms 69248 KB Output is correct
14 Correct 48 ms 69240 KB Output is correct
15 Correct 47 ms 69240 KB Output is correct
16 Correct 50 ms 69240 KB Output is correct
17 Correct 54 ms 69344 KB Output is correct
18 Correct 51 ms 69240 KB Output is correct
19 Correct 47 ms 69240 KB Output is correct
20 Correct 60 ms 70392 KB Output is correct
21 Correct 57 ms 70400 KB Output is correct
22 Correct 63 ms 70648 KB Output is correct
23 Correct 75 ms 70648 KB Output is correct
24 Correct 58 ms 70564 KB Output is correct
25 Correct 53 ms 70520 KB Output is correct
26 Correct 67 ms 70648 KB Output is correct
27 Correct 58 ms 70264 KB Output is correct
28 Correct 53 ms 70392 KB Output is correct
29 Correct 60 ms 70520 KB Output is correct
30 Correct 57 ms 70648 KB Output is correct
31 Correct 55 ms 70648 KB Output is correct
32 Correct 68 ms 70648 KB Output is correct
33 Correct 58 ms 70648 KB Output is correct
34 Correct 434 ms 92636 KB Output is correct
35 Incorrect 480 ms 92792 KB Output isn't correct
36 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 47 ms 69248 KB Output is correct
2 Correct 46 ms 69248 KB Output is correct
3 Correct 51 ms 69240 KB Output is correct
4 Correct 49 ms 69264 KB Output is correct
5 Correct 49 ms 69240 KB Output is correct
6 Correct 48 ms 69368 KB Output is correct
7 Correct 49 ms 69248 KB Output is correct
8 Correct 47 ms 69368 KB Output is correct
9 Correct 47 ms 69332 KB Output is correct
10 Correct 47 ms 69240 KB Output is correct
11 Correct 46 ms 69240 KB Output is correct
12 Correct 47 ms 69244 KB Output is correct
13 Correct 51 ms 69248 KB Output is correct
14 Correct 48 ms 69240 KB Output is correct
15 Correct 47 ms 69240 KB Output is correct
16 Correct 50 ms 69240 KB Output is correct
17 Correct 54 ms 69344 KB Output is correct
18 Correct 51 ms 69240 KB Output is correct
19 Correct 47 ms 69240 KB Output is correct
20 Correct 60 ms 70392 KB Output is correct
21 Correct 57 ms 70400 KB Output is correct
22 Correct 63 ms 70648 KB Output is correct
23 Correct 75 ms 70648 KB Output is correct
24 Correct 58 ms 70564 KB Output is correct
25 Correct 53 ms 70520 KB Output is correct
26 Correct 67 ms 70648 KB Output is correct
27 Correct 58 ms 70264 KB Output is correct
28 Correct 53 ms 70392 KB Output is correct
29 Correct 60 ms 70520 KB Output is correct
30 Correct 57 ms 70648 KB Output is correct
31 Correct 55 ms 70648 KB Output is correct
32 Correct 68 ms 70648 KB Output is correct
33 Correct 58 ms 70648 KB Output is correct
34 Correct 434 ms 92636 KB Output is correct
35 Incorrect 480 ms 92792 KB Output isn't correct
36 Halted 0 ms 0 KB -