FAMILYTREE 시간초과 질문드려요..

  • Spotlight
    Spotlight

    알고리즘 문제해결전략 책에 있는 족보 탐험 문제 소스와 RMQ소스를 가져다 썼는데 뭐가 문젠지 시간초과가 나네요..
    제가 잘못 구현한 것인지.. 책에있는 소스로는 원래 시간초과가 나는것인지 질문드려요..ㅠㅠ 며칠째 LCA만 잡고있는데 힘드네요..

    #include <cstdio>
    #include <algorithm>
    #include <vector>
    #include <climits>
    #include <cstring>
    
    using namespace std;
    
    const int MAX_N = 500000;
    vector<int> ch[MAX_N];
    int no2serial[MAX_N];
    int serial2no[MAX_N];
    int locInTrip[MAX_N];
    int depth[MAX_N];
    int nextSerial;
    int N, M, C;
    int rangeMin[MAX_N];
    
    
    int init(const vector<int>& trip, int left, int right, int node)
    {
        if(left == right){
            return rangeMin[node] = trip[left];
        }
        int mid = (left + right) / 2;
        int leftMin = init(trip, left, mid, node*2);
        int rightMin = init(trip, mid+1, right, node*2+1);
        return rangeMin[node] = min(leftMin, rightMin);
    }
    
    int query(int l, int r, int node, int nodeLeft, int nodeRight)
    {
        if(r < nodeLeft || nodeRight < l) return INT_MAX;
        if(l <= nodeLeft && nodeRight <= r)
            return rangeMin[node];
        int mid = (nodeLeft + nodeRight) / 2;
        return min(query(l, r, node*2, nodeLeft, mid), query(l,r,node*2+1,mid+1,nodeRight));
    }
    
    void traverse(int here, int d, vector<int> &trip)
    {
        no2serial[here] = nextSerial;
        serial2no[nextSerial] = here;
        nextSerial++;
    
        depth[here] = d;
        locInTrip[here] = trip.size();
        trip.push_back(no2serial[here]);
    
        for(int i=0; i<ch[here].size(); i++){
            traverse(ch[here][i], d+1, trip);
            trip.push_back(no2serial[here]);
        }
    }
    
    int LCA(int u, int v)
    {
        int lu = locInTrip[u];
        int lv = locInTrip[v];
    
        if(lu > lv) swap(lu, lv);
        int lca = serial2no[query(lu,lv,1,0,2*N-2)];
        return depth[u] + depth[v] - 2 * depth[lca];
    }
    
    
    
    int main()
    {
        scanf("%d", &C);
        while(C--){
            scanf("%d %d", &N, &M);
            int a, b;
    
            for(int i=0;i<=N;i++){
                ch[i].clear();
            }
            for(int i=1;i<=N-1;i++){
                scanf("%d", &a);
    
                ch[a].push_back(i);
            }
    
            vector<int> tr;
            traverse(0, 0, tr);
    
            init(tr, 0, 2*N-2, 1);
    
            for(int i=0;i<M;i++){
                scanf("%d %d", &a,&b);
                printf("%d\n", LCA(a,b));
            }
        }
        return 0;
    }
    

    7년 전
1개의 댓글이 있습니다.
  • JongMan
    JongMan

    테스트 케이스가 끝날 때마다 초기화가 잘 이루어지지 않는 것 같네요~


    7년 전 link
  • 정회원 권한이 있어야 커멘트를 다실 수 있습니다. 정회원이 되시려면 온라인 저지에서 5문제 이상을 푸시고, 가입 후 7일 이상이 지나셔야 합니다. 현재 문제를 푸셨습니다.