[SPOJ-COT]Count on a tree
[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相关推荐
- SPOJ - COT Count on a tree [LCA+主席树]【数据结构】
题目链接:http://www.spoj.com/problems/COT/en/ -------------------------------------- COT - Count on a tr ...
- SPOJ - COT Count on a tree(LCA+主席树+离散化)
题目链接:点击查看 题目大意:给出一棵树,每个点都有一个权值,现在给出m个询问,每次询问的格式是u,v,k,要求输出u-v这条路径上第k大的数 题目分析:一看到第k大的数就会想到主席树,既然是在树上的 ...
- SPOJ COT Count on a tree 主席树
题意: 给\(n(1 \leq n \leq 10^5)\)一棵树,每个点有个权值. 还有\(m(1 \leq m \leq 10^5)\)个询问: \(u \, v \, k\),查询路径\(u \ ...
- SPOJ COT Count on a tree(主席树+倍增lca)
思路:这个题其实就是树上的第k小,主席树的本质还是类似于前缀和一样的结构,所以是完全相同的,所以我们在树上也可以用同样的方法,我们对于每一个节点进行建树,然后和普通的树上相同,ab之间的距离是等于 r ...
- 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 ...
- 【SPOJ】Count On A Tree II(树上莫队)
[SPOJ]Count On A Tree II(树上莫队) 题面 洛谷 Vjudge 洛谷上有翻译啦 题解 如果不在树上就是一个很裸很裸的莫队 现在在树上,就是一个很裸很裸的树上莫队啦. #incl ...
- 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 ...
- BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )
Orz..跑得还挺快的#10 自从会树链剖分后LCA就没写过倍增了... 这道题用可持久化线段树..点x的线段树表示ROOT到x的这条路径上的权值线段树 ----------------------- ...
- BZOJ 2588 Spoj 10628 Count on a tree | 树上主席树
BZOJ 2588 Count on a tree 题面 求树上两点之间路径上第k大的点权. 题解 一开始看到这道题觉得是树剖,然后又听说是主席树,然后以为是主席树+树剖,差点没吓死-- 然后发现,如 ...
- 主席树 || 可持久化线段树 || 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) ...
最新文章
- Linux调试技术介绍
- 【收藏】从 0 到 1 学习 elasticsearch ,这一篇就够了!
- Java线程同步的一些例子
- arcgis的python接口_arcgis-Python的ArcGIS API-Esri Screenshots
- 打印杨辉三角(数组练习)
- (转)Struts2访问Servlet的API及......
- php capistrano,使用Capistrano 做自动化部署(适合所有语言所有框架)视频课程
- Red Hat Enterprise Linux上配置SQL Server Always On Availability Group
- 数据库的水平扩展与垂直扩展
- 计算机的创新产品,这几种电脑创新功能 空有喝彩没人买
- php正则表达式修饰符详解
- ThinkPHP3.2中使用第三方库(phpQuery)
- 全国路网数据SHP、全国矢量数据 行政区划边界(省市区县乡镇)、行政地名
- 500万条微博数据来源分析
- Echarts Y轴遮挡解决方案
- 未来10年 人工智能将如何影响淘宝发展?
- 在不停业务的情况下重启ES集群中的节点
- TOPSIS(优劣解距离法)【附Python实现代码及可视化代码】
- 西北工业大学计算机学院推免,2021年西北工业大学接收推荐免试研究生预报名的通知...
- 腾讯云仪征数据中心开服,辐射长三角产业数字化升级
热门文章
- 疯狂位图之——位图实现12GB无重复大整数集排序
- c# 正则过滤非中文字符
- 【WPF】MeshGeometry3D中的Normals和TextureCoordinates属性
- SmartGridView(VB)
- Flutter 28: 图解 ListView/GridView 混用时滑动冲突小尝试
- 在嵌入式学习过程中,很多人都有这样的困惑!——为什么要学习嵌入式技术?...
- Android 访问WebService
- 九度 题目1044:Pre-Post
- php -- 读取大文件
- cocos2dx 3.x ccPositionTextureColor_vert与ccPositionTextureColor_noMVP_vert