[SPOJ-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
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 

思路

这是一个把主席树推广到树上的题。我们首先思考一下,普通的主席树/权值线段树只能对线性的区间进行操作,我们要做的,就是把一棵树分解成一个线性的结构,同时便于进行题目规定的查询操作。

因为这道题是求路径到LCA上的k小值。我们就可以把每个节点到根节点的路径建一棵树。每个节点的子节点对应的线段树可以从父节点线段树继承得到。复杂度\(n\log_2 n\)。

那解法就很显然了,我们先对根节点建一个权值线段树,然后按照DFS序依次遍历整棵树,将父节点继承下来,成为一颗新的树。

对于查询\((i,j,k)\),我们只需要求出一棵包含\(i\)到\(j\)所有点权值的权值线段树,按照k小值标准查询方式查询即可。

那么我们设这棵线段树为\(T_a\),从节点\(i\)到根节点的权值线段树为\(T_i\)。那么很显然:
\[ T_a=T_i+T_j-T_{LCA(i,j)}-T_{fa[LCA(i,j)]} \]
注意,至于为什么最后一项是\(fa[LCA(i,j)]\),仔细想一想就能发现如果两个都是\(LCA(i,j)\),会把\(LCA(i,j)\)多减一次。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define maxn (int)(1e5+1000)
int
n,m,idx,len,ls[maxn*21],rs[maxn*21],sum[maxn*21],a[maxn],sorted[maxn],head[maxn],cnt,rt[maxn],f[maxn];
struct gg{int u,v,next;
}side[maxn*2];
int getid(int x){return lower_bound(sorted+1,sorted+1+len,x)-sorted;
}
void insert(int u,int v){gg q={u,v,head[u]};side[++cnt]=q;head[u]=cnt;return;
}
int build(int l,int r){int now=++idx;if(l==r)return now;int mid=(l+r)>>1;ls[now]=build(l,mid);rs[now]=build(mid+1,r);return now;
}
int update(int last,int pos,int l,int r){int now=++idx;rs[now]=rs[last],ls[now]=ls[last],sum[now]=sum[last]+1;if(l==r){return now; }int mid=(l+r)>>1;if(pos<=mid){ls[now]=update(ls[last],pos,l,mid);}else{rs[now]=update(rs[last],pos,mid+1,r);}return now;
}
void dfs(int now,int fa){f[now]=fa;rt[now]=update(rt[fa],getid(a[now]),1,len);//testfor(int i=head[now];i;i=side[i].next){int v=side[i].v;if(v==fa)continue;dfs(v,now);}return;
}
int query(int p1,int p2,int p3,int p4,int k,int l,int r){//i,j,lca,fa[lca]int tot=sum[ls[p1]]+sum[ls[p2]]-sum[ls[p3]]-sum[ls[p4]];int mid=(l+r)>>1;if(l==r)return l;if(k<=tot){return query(ls[p1],ls[p2],ls[p3],ls[p4],k,l,mid);}else{return query(rs[p1],rs[p2],rs[p3],rs[p4],k-tot,mid+1,r);}return 0;
}
/*-----------------------*/
int fa[maxn][30],dep[maxn];
void dfs1(int u, int f) {dep[u] = dep[f] + 1, fa[u][0] = f;for (int i = 1;i <= 20;i++) fa[u][i] = fa[fa[u][i - 1]][i - 1];for (int i = head[u];i;i = side[i].next)if (side[i].v != f) dfs1(side[i].v, u);
}
int lca(int a1, int b1) {if (dep[a1] < dep[b1]) swap(a1, b1);for (int i = 20;i >= 0;i--) if (dep[fa[a1][i]] >= dep[b1]) a1 = fa[a1][i];if (a1 == b1) return a1;for (int i = 20;i >= 0;i--) if (fa[a1][i] != fa[b1][i]) a1 =fa[a1][i],b1 = fa[b1][i];return fa[a1][0];
}/*------------------------*/
int main(){//freopen("in","r",stdin);scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%d",&a[i]);sorted[i]=a[i];}sort(sorted+1,sorted+1+n);len=unique(sorted+1,sorted+1+n)-sorted-1;for(int i=1;i<n;i++){int u,v;scanf("%d%d",&u,&v);insert(u,v);insert(v,u);}rt[0]=build(1,len);dfs(1,0);dfs1(1,0);for(int i=1;i<=m;i++){int u,v,k;scanf("%d%d%d",&u,&v,&k);int ans=query(rt[u],rt[v],rt[(lca(u,v))],rt[f[lca(u,v)]],k,1,len);printf("%d\n",sorted[ans]);}return 0;
}

转载于:https://www.cnblogs.com/GavinZheng/p/10826417.html

[SPOJ-COT]Count on a tree相关推荐

  1. SPOJ - COT Count on a tree [LCA+主席树]【数据结构】

    题目链接:http://www.spoj.com/problems/COT/en/ -------------------------------------- COT - Count on a tr ...

  2. SPOJ - COT Count on a tree(LCA+主席树+离散化)

    题目链接:点击查看 题目大意:给出一棵树,每个点都有一个权值,现在给出m个询问,每次询问的格式是u,v,k,要求输出u-v这条路径上第k大的数 题目分析:一看到第k大的数就会想到主席树,既然是在树上的 ...

  3. SPOJ COT Count on a tree 主席树

    题意: 给\(n(1 \leq n \leq 10^5)\)一棵树,每个点有个权值. 还有\(m(1 \leq m \leq 10^5)\)个询问: \(u \, v \, k\),查询路径\(u \ ...

  4. SPOJ COT Count on a tree(主席树+倍增lca)

    思路:这个题其实就是树上的第k小,主席树的本质还是类似于前缀和一样的结构,所以是完全相同的,所以我们在树上也可以用同样的方法,我们对于每一个节点进行建树,然后和普通的树上相同,ab之间的距离是等于 r ...

  5. bzoj 2588 Spoj 10628. Count on a tree (可持久化线段树)

    Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MB Submit: 7669  Solved: 1894 [Sub ...

  6. 【SPOJ】Count On A Tree II(树上莫队)

    [SPOJ]Count On A Tree II(树上莫队) 题面 洛谷 Vjudge 洛谷上有翻译啦 题解 如果不在树上就是一个很裸很裸的莫队 现在在树上,就是一个很裸很裸的树上莫队啦. #incl ...

  7. BZOJ 2588: Spoj 10628. Count on a tree 树上跑主席树

    2588: Spoj 10628. Count on a tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/J ...

  8. BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )

    Orz..跑得还挺快的#10 自从会树链剖分后LCA就没写过倍增了... 这道题用可持久化线段树..点x的线段树表示ROOT到x的这条路径上的权值线段树 ----------------------- ...

  9. BZOJ 2588 Spoj 10628 Count on a tree | 树上主席树

    BZOJ 2588 Count on a tree 题面 求树上两点之间路径上第k大的点权. 题解 一开始看到这道题觉得是树剖,然后又听说是主席树,然后以为是主席树+树剖,差点没吓死-- 然后发现,如 ...

  10. 主席树 || 可持久化线段树 || LCA || BZOJ 2588: Spoj 10628. Count on a tree || Luogu P2633 Count on a tree...

    题面: Count on a tree 题解: 主席树维护每个节点到根节点的权值出现次数,大体和主席树典型做法差不多,对于询问(X,Y),答案要计算ans(X)+ans(Y)-ans(LCA(X,Y) ...

最新文章

  1. Linux调试技术介绍
  2. 【收藏】从 0 到 1 学习 elasticsearch ,这一篇就够了!
  3. Java线程同步的一些例子
  4. arcgis的python接口_arcgis-Python的ArcGIS API-Esri Screenshots
  5. 打印杨辉三角(数组练习)
  6. (转)Struts2访问Servlet的API及......
  7. php capistrano,使用Capistrano 做自动化部署(适合所有语言所有框架)视频课程
  8. Red Hat Enterprise Linux上配置SQL Server Always On Availability Group
  9. 数据库的水平扩展与垂直扩展
  10. 计算机的创新产品,这几种电脑创新功能 空有喝彩没人买
  11. php正则表达式修饰符详解
  12. ThinkPHP3.2中使用第三方库(phpQuery)
  13. 全国路网数据SHP、全国矢量数据 行政区划边界(省市区县乡镇)、行政地名
  14. 500万条微博数据来源分析
  15. Echarts Y轴遮挡解决方案
  16. 未来10年 人工智能将如何影响淘宝发展?
  17. 在不停业务的情况下重启ES集群中的节点
  18. TOPSIS(优劣解距离法)【附Python实现代码及可视化代码】
  19. 西北工业大学计算机学院推免,2021年西北工业大学接收推荐免试研究生预报名的通知...
  20. 腾讯云仪征数据中心开服,辐射长三角产业数字化升级

热门文章

  1. 疯狂位图之——位图实现12GB无重复大整数集排序
  2. c# 正则过滤非中文字符
  3. 【WPF】MeshGeometry3D中的Normals和TextureCoordinates属性
  4. SmartGridView(VB)
  5. Flutter 28: 图解 ListView/GridView 混用时滑动冲突小尝试
  6. 在嵌入式学习过程中,很多人都有这样的困惑!——为什么要学习嵌入式技术?...
  7. Android 访问WebService
  8. 九度 题目1044:Pre-Post
  9. php -- 读取大文件
  10. cocos2dx 3.x ccPositionTextureColor_vert与ccPositionTextureColor_noMVP_vert