SPOJ-COT-Count on a tree
来源:互联网 发布:无线传感器软件 编辑:程序博客网 时间:2024/05/19 17:57
COT-Count on a tree
You are given a tree with N nodes.The tree nodes are numbered from 1 to N.Each node has an integer weight.
We will ask you to perform the following operation:
u v k : ask for the kth minimum weight on the path from node u to node v
Input
In the first line there are two integers N and M.(N,M<=100000)
In the second line there are N integers.The ith integer denotes the weight of the ith node.
In the next N-1 lines,each line contains two integers u v,which describes an edge (u,v).
In the next M lines,each line contains three integers u v k,which means an operation asking for the kth minimum weight on the path from node u to node v.
Output
For each operation,print its result.
Example
Input:
8 5
8 5
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 8
2 5 1
2 5 2
2 5 3
2 5 4
7 8 2
Output:
2
8
9
105
7
题目大意:树上任意两点之间路径中的第k小
解题思路:主席树+LCA
#include<iostream>#include<cstdio>#include<vector>#include<algorithm>#include<map>#include<cmath>#include<set>#include<cstring>using namespace std;typedef long long LL;const int MAXN=1e5+5;int n,m,tot;int cnt,head[MAXN];int len,root[MAXN],lson[MAXN*20],rson[MAXN*20],val[MAXN*20];int num,dep[MAXN*2],ver[MAXN*2],fst[MAXN],dp[MAXN*2][20],fa[MAXN];bool vis[MAXN];int a[MAXN],b[MAXN];struct Edge{ int to,nxt;}e[MAXN*2];void addedge(int u,int v){ e[cnt].to=v; e[cnt].nxt=head[u]; head[u]=cnt++;}void build(int l,int r,int &rt){ rt=++tot; val[rt]=0; if(l==r) return; int mid=(l+r)>>1; build(l,mid,lson[rt]); build(mid+1,r,rson[rt]);}void update(int pre,int &rt,int l,int r,int v){ rt=++tot; lson[rt]=lson[pre];rson[rt]=rson[pre];val[rt]=val[pre]+1; if(l==r) return; int mid=(l+r)>>1; if(v<=mid) update(lson[pre],lson[rt],l,mid,v); else update(rson[pre],rson[rt],mid+1,r,v);}void dfs(int u,int fat,int d){ vis[u]=true;ver[++num]=u;dep[num]=d;fst[u]=num;fa[u]=fat; update(root[fat],root[u],1,len,a[u]); for(int i=head[u];i!=-1;i=e[i].nxt) { int to=e[i].to; if(!vis[to]) { dfs(to,u,d+1); ver[++num]=u;dep[num]=d; } }}void ST(int n){ for(int i=1;i<=n;i++) dp[i][0]=i; for(int j=1;(1<<j)<=n;j++) { for(int i=1;i<=n-(1<<j)+1;i++) { if(dep[dp[i][j-1]]<dep[dp[i+(1<<(j-1))][j-1]]) dp[i][j]=dp[i][j-1]; else dp[i][j]=dp[i+(1<<(j-1))][j-1]; } }}int RMQ(int l,int r){ int k=log(r-l+1)/log(2); if(dep[dp[l][k]]<dep[dp[r-(1<<k)+1][k]]) return dp[l][k]; else return dp[r-(1<<k)+1][k];}int LCA(int u,int v){ u=fst[u],v=fst[v]; if(u>v) swap(u,v); int res=RMQ(u,v); return ver[res];}int query(int ss,int tt,int lca,int lcafa,int l,int r,int k){ if(l==r) return l; int mid=(l+r)>>1; int tmp=val[lson[ss]]+val[lson[tt]]-val[lson[lca]]-val[lson[lcafa]]; if(k<=tmp) return query(lson[ss],lson[tt],lson[lca],lson[lcafa],l,mid,k); else return query(rson[ss],rson[tt],rson[lca],rson[lcafa],mid+1,r,k-tmp);}int main(){ while(scanf("%d%d",&n,&m)!=EOF) { for(int i=1;i<=n;i++) { scanf("%d",&a[i]); b[i]=a[i]; } sort(b+1,b+1+n); len=unique(b+1,b+1+n)-(b+1); for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+len+1,a[i])-b; cnt=0; memset(head,-1,sizeof(head)); int u,v,k; for(int i=1;i<=n-1;i++) { scanf("%d%d",&u,&v); addedge(u,v);addedge(v,u); } tot=0; build(1,len,root[0]); num=0; memset(vis,false,sizeof(vis)); dfs(1,0,1); ST(2*n-1); int lca; for(int i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&k); lca=LCA(u,v); printf("%d\n",b[query(root[u],root[v],root[lca],root[fa[lca]],1,len,k)]); } } return 0;}
- spoj cot Count on a tree
- SPOJ COT 10628 Count on a tree
- SPOJ-COT-Count on a tree
- SPOJ COT Count on a tree
- SPOJ COT - Count on a tree树链剖分加主席树
- 【SPOJ-COT】Count on a tree【主席树】【LCA】
- SPOJ COT Count on a tree 树上第k小
- [BZOJ 2588][SPOJ COT]Count On a Tree(DFS序主席树)
- [省选前题目整理][BZOJ 2588][SPOJ COT]Count On a Tree(DFS序主席树)
- 【可持久化线段树】[SPOJ COT]Count on a tree
- SPOJ COT Count on a tree (树上k大 主席树模板)
- 【spoj】【COT - Count on a tree】【可持久化线段树】
- SPOJ Count on a tree
- Count on a tree SPOJ
- Count on a tree SPOJ
- spoj 10628 Count on a tree
- SPOJ 10628. Count on a tree
- 【主席树】 SPOJ Count on a tree
- phpcms 路由配置
- C语言生成可执行文件过程(编译过程)
- 菜鸟:自己写了一个轮播代码供分为参考,如果有什么地方你有更好的方法,可以给我留言
- [日推荐]『表情集市』斗图必备
- 1.4算法研究-全排列
- SPOJ-COT-Count on a tree
- Dubbo配置以及使用总结
- java中使用异或的方式对文件进行加密解密
- C# SignalR 实时通讯 聊天室
- [转]ExtJS学习------Ext.window属性详解
- 简单的频道管理(第一步)
- DirectX9学习(一)
- 使用spring jdbc查询对象
- 写给立志做码农的大学生