题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4366
题目大意:求一个结点的子树中能力值大于它且忠诚值最大的结点是哪个。
题目思路:线段树,按能力值由大到小加入线段树,能力值相同时先加id小的,这样能保证不会有能力值和父亲相同的儿子加到父亲前面,这样每次查询就能得到答案,由于忠诚值不同,可以进行hash或用map。话说数据好水啊,错误代码都能过。。
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<string> #include<queue> #include<algorithm> #include<vector> #include<stack> #include<list> #include<iostream> #include<map> using namespace std; #define inf 0x3f3f3f3f #define M 50010 int max(int a,int b) { return a>b?a:b; } int min(int a,int b) { return a<b?a:b; } int eid,st[M],ed[M],ab[M],lo[M],p[M],stamp,rec,id[M],ans[M]; int mp[1010000]; struct node { int to,next; }e[2*M]; struct nn { int l,r,ma; int mid() { return (l+r)>>1; } }T[4*M]; bool cmp(int a,int b) { if(ab[a]==ab[b]) return a<b; return ab[a]>ab[b]; } void addedge(int u,int v) { e[eid].to=v; e[eid].next=p[u]; p[u]=eid++; } void dfs(int u) { int i,v; st[u]=stamp++; for(i=p[u];i!=-1;i=e[i].next) { v=e[i].to; dfs(v); } ed[u]=stamp-1; } void build(int l,int r,int rt) { T[rt].l=l;T[rt].r=r; T[rt].ma=-inf; if(l==r) return; int mid=T[rt].mid(); build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); } void modify(int x,int rt,int data) { if(T[rt].l==T[rt].r) { T[rt].ma=data; return; } int mid=T[rt].mid(); if(x<=mid) modify(x,rt<<1,data); else modify(x,rt<<1|1,data); T[rt].ma=max(T[rt<<1].ma,T[rt<<1|1].ma); } void query(int l,int r,int rt) { if(l==T[rt].l&&r==T[rt].r) { rec=max(rec,T[rt].ma); return ; } int mid=T[rt].mid(); if(r<=mid) query(l,r,rt<<1); else if(l>mid) query(l,r,rt<<1|1); else { query(l,mid,rt<<1); query(mid+1,r,rt<<1|1); } } int main() { int i,u,t,n,m,x; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); eid=0; stamp=0; memset(mp,0,sizeof(mp)); memset(p,-1,sizeof(p)); for(i=1;i<n;i++) { scanf("%d%d%d",&u,&lo[i],&ab[i]); id[i]=i; mp[lo[i]]=i; addedge(u,i); } sort(id+1,id+n,cmp); dfs(0); build(0,n-1,1); for(i=1;i<n;i++) { if(st[id[i]]==ed[id[i]]) { ans[id[i]]=-1; } else { rec=-inf; query(st[id[i]]+1,ed[id[i]],1); if(rec==-inf) ans[id[i]]=-1; else { ans[id[i]]=mp[rec]; } } modify(st[id[i]],1,lo[id[i]]); } for(i=0;i<m;i++) { scanf("%d",&x); printf("%d\n",ans[x]); } } }