Lightoj 1128 - Greatest Parent

Gate

倍增模板,在一个严格小根堆中,给定$x,y$,求$x$的祖先中$≥y$的最高点。

注意清零

#include<cstdio>
#include<iostream>
#include<cstring>
#define MogeKo qwq
using namespace std;
const int maxn = 1e5+10;
int t,n,q,val[maxn],cnt;
int dpth[maxn],p[maxn][20];
int to[maxn],head[maxn],nxt[maxn];

void add(int x,int y) {
    to[++cnt] = y;
    nxt[cnt] = head[x];
    head[x] = cnt;
}

void dfs(int x,int fa) {
    dpth[x] = dpth[fa]+1;
    p[x][0] = fa;
    for(int i = 1; (1<<i)<=dpth[x]; i++)
        p[x][i] = p[p[x][i-1]][i-1];
    for(int i = head[x]; i; i = nxt[i]) {
        if(to[i] == fa)continue;
        dfs(to[i],x);
    }
}

int solve(int x,int y) {
    for(int i = 19; i >= 0; i--) {
        if(val[p[x][i]] >= y) x = p[x][i];
        if(x==0 || val[x]==y)break;
    }
    return x;
}

int main() {
    scanf("%d",&t);
    for(int j = 1;j <= t;j++) {
        printf("Case %d:\n",j);
        memset(to,0,sizeof(to));
        memset(head,0,sizeof(head));
        memset(nxt,0,sizeof(nxt));
        memset(p,0,sizeof(p));
        cnt = 0;
        val[0] = 1;
        dpth[0] = 0;
        scanf("%d%d",&n,&q);
        int x,y;
        for(int i = 1; i <= n-1; i++) {
            scanf("%d%d",&x,&y);
            add(x,i);
            val[i] = y;
        }
        dfs(0,0);
        for(int i = 1; i <= q; i++) {
            scanf("%d%d",&x,&y);
            printf("%d\n",solve(x,y));
        }
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/mogeko/p/10609251.html