Lightoj 1128 - Greatest Parent
倍增模板,在一个严格小根堆中,给定$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; }