1 3 1 2 7 2 3 5 4 3 10 3 7 3 6 3 4
7 7 5 -1Hint2<=n<=10^5 2<=Q<=10^5 1<=W,Y<=10^9 The data is guaranteed that your program will overflow if you use recursion.
分析:首先把边的权值从小到达排列,然后把询问的y值也从小到达排列,然后对于每一个询问,把小于y值的边更新到线段树中,接着求出该次询问的最大值,把答案记录到原来顺序的数组里面,最后输出即可;
程序:
#pragma comment(linker, "/STACK:102400000,102400000") #include"stdio.h" #include"string.h" #include"iostream" #include"map" #include"string" #include"queue" #include"stdlib.h" #include"math.h" #define M 100009 #define inf 100000000 using namespace std; struct node { int u,v,next; }edge[M*2]; int t,head[M],son[M],fa[M],num[M],p[M],fp[M],deep[M],cnt[M],pos,top[M],Max; void init() { t=pos=0; memset(head,-1,sizeof(head)); memset(son,-1,sizeof(son)); } void add(int u,int v) { edge[t].u=u; edge[t].v=v; edge[t].next=head[u]; head[u]=t++; } void dfs(int u,int f,int d) { deep[u]=d; fa[u]=f; num[u]=1; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(v!=f) { dfs(v,u,d+1); num[u]+=num[v]; if(son[u]==-1||num[son[u]]<num[v]) son[u]=v; } } } void getpos(int u,int sp) { top[u]=sp; p[u]=pos++; fp[p[u]]=u; if(son[u]==-1)return; getpos(son[u],sp); for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(v!=fa[u]&&v!=son[u]) getpos(v,v); } } struct Node { int l,r,maxi; }tree[M*5]; void pushup(int i) { tree[i].maxi=max(tree[i*2].maxi,tree[i*2+1].maxi); } void make(int l,int r,int i) { tree[i].l=l; tree[i].r=r; if(l==r) { tree[i].maxi=-inf; return; } int mid=(l+r)/2; make(l,mid,i*2); make(mid+1,r,i*2+1); pushup(i); } void updata(int p,int q,int i) { if(tree[i].r==p&&tree[i].l==p) { tree[i].maxi=q; return; } int mid=(tree[i].l+tree[i].r)/2; if(p<=mid) updata(p,q,i*2); else updata(p,q,i*2+1); pushup(i); } void query(int l,int r,int i) { if(tree[i].l==l&&tree[i].r==r) { Max=max(Max,tree[i].maxi); return; } int mid=(tree[i].r+tree[i].l)/2; if(r<=mid) query(l,r,i*2); else if(l>mid) query(l,r,i*2+1); else { query(l,mid,i*2); query(mid+1,r,i*2+1); } pushup(i); } int findmax(int u,int v) { int f1=top[u]; int f2=top[v]; int ans=-inf; while(f1!=f2) { if(deep[f1]<deep[f2]) { swap(f1,f2); swap(u,v); } Max=-inf; query(p[f1],p[u],1); ans=max(ans,Max); u=fa[f1]; f1=top[u]; } if(v==u) return ans; if(deep[u]>deep[v]) swap(u,v); Max=-inf; query(p[son[u]],p[v],1); ans=max(ans,Max); return ans; } struct Edge { int u,v,w,x,y,kk; }e[M],Q[M]; int cmp(const void *a,const void *b) { return (*(struct Edge*)a).w-(*(struct Edge*)b).w; } int cmpy(const void *a,const void *b) { return (*(struct Edge*)a).y-(*(struct Edge*)b).y; } int main() { int T; cin>>T; while(T--) { int n,i; init(); scanf("%d",&n); for(i=0;i<n-1;i++) { scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w); add(e[i].u,e[i].v); add(e[i].v,e[i].u); } dfs(1,1,0); getpos(1,1); make(1,pos-1,1); qsort(e,n-1,sizeof(e[0]),cmp); int que; scanf("%d",&que); for(i=0;i<que;i++) { scanf("%d%d",&Q[i].x,&Q[i].y); Q[i].kk=i; } qsort(Q,que,sizeof(Q[0]),cmpy); int j=0; for(i=0;i<que;i++) { while(j<n-1&&e[j].w<=Q[i].y) { if(deep[e[j].u]<deep[e[j].v]) swap(e[j].u,e[j].v); updata(p[e[j].u],e[j].w,1); j++; } cnt[Q[i].kk]=findmax(1,Q[i].x); if(cnt[Q[i].kk]<=-inf) cnt[Q[i].kk]=-1; } for(i=0;i<que;i++) printf("%d\n",cnt[i]); } return 0; }