的权,保持,快排。n*logn*q
#include<iostream> //187MS #include<algorithm> #include<cstdio> #include<vector> using namespace std; int n,q; int w[90000]; vector<vector<int> >e(160100); int lev[80010];int vis[80010]; int fa[80010]; void dfs_getlev(int u) //dfs { for(int i=0;i<e[u].size();i++) { int v=e[u][i]; if(!vis[v]) { vis[v]=1; lev[v]=lev[u]+1; fa[v]=u; dfs_getlev(v); } } } bool my(int a,int b) { return a>b; } int find_lca(int k,int a,int b) //在线lca,按层次向上走。 { vector<int> ans; if(lev[a]>lev[b]) { int temp=a;a=b;b=temp; } while(lev[b]>lev[a]) { ans.push_back(w[b]); b=fa[b]; } while(a!=b) { ans.push_back(w[b]); ans.push_back(w[a]); a=fa[a]; b=fa[b]; } ans.push_back(w[b]); if(k>ans.size()) return -1; sort(ans.begin(),ans.end(),my); return ans[k-1]; } int main() { cin>>n>>q; for(int i=1;i<=n;i++) scanf("%d",&w[i]); int ta,tb; for(int i=0;i<n-1;i++) { scanf("%d%d",&ta,&tb); e[ta].push_back(tb); e[tb].push_back(ta); } vis[1]=lev[1]=1; dfs_getlev(1); int k,a,b; while(q--) { scanf("%d%d%d",&k,&a,&b); if(k>0) { int anss =find_lca(k,a,b); if(anss!=-1) printf("%d\n",anss); else printf("invalid request!\n"); } else { w[a]=b; } } return 0; }
hdu3078 建层次树+在线LCA算法+排序,布布扣,bubuko.com
原文地址:http://blog.csdn.net/u011498819/article/details/25901609