【SPOJ10628】Count on a tree
题目大意:给定一棵 N 个节点的树,点有点权,要求回答 M 个询问,每次询问点 u 到点 v 的简单路径(链)上权值第 K 小是多少。
题解:学习到了树上主席树。
主席树维护序列时,每次将后一个点的树建立在前一个点的树上,由此构成一个前缀和,并利用可以在线段树上二分的性质来求 K 小值。树上主席树维护的是每个节点到根节点路径上的前缀和,即:每个点的主席树建立在其父节点的主席树基础上。回答答案时,只需在 u,v,lca(u,v),fa[lca(u,v)] 的四棵主席树上面二分答案即可。
代码如下
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=1e5+10;
int n,m,val[maxn],d[maxn],len;
int f[maxn][21],dep[maxn];
struct Graph{
int nxt,to;
}e[maxn<<1];
int tot=1,head[maxn];
inline void add_edge(int from,int to){
e[++tot]=(Graph){head[from],to},head[from]=tot;
}
struct node{
#define ls(x) t[x].lc
#define rs(x) t[x].rc
int lc,rc,sum;
}t[maxn*20];
int cnt,root[maxn];
inline void pushup(int o){t[o].sum=t[ls(o)].sum+t[rs(o)].sum;}
int insert(int pre,int l,int r,int pos,int value){
int o=++cnt;
t[o]=t[pre];
if(l==r){t[o].sum+=value;return o;}
int mid=l+r>>1;
if(pos<=mid)ls(o)=insert(ls(pre),l,mid,pos,value);
else rs(o)=insert(rs(pre),mid+1,r,pos,value);
return pushup(o),o;
}
int query(int a,int b,int c,int d,int l,int r,int k){
if(l==r)return l;
int mid=l+r>>1;
int sum=t[ls(c)].sum+t[ls(d)].sum-t[ls(a)].sum-t[ls(b)].sum;
if(k<=sum)return query(ls(a),ls(b),ls(c),ls(d),l,mid,k);
else return query(rs(a),rs(b),rs(c),rs(d),mid+1,r,k-sum);
}
inline int ask(int x){return lower_bound(d+1,d+len+1,x)-d;}
void read_and_parse(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&val[i]),d[++len]=val[i];
for(int i=1,x,y;i<n;i++){
scanf("%d%d",&x,&y);
add_edge(x,y),add_edge(y,x);
}
sort(d+1,d+len+1);
len=unique(d+1,d+len+1)-d-1;
}
void dfs(int u,int fa){
dep[u]=dep[fa]+1,f[u][0]=fa;
for(int i=1;i<=20;i++)f[u][i]=f[f[u][i-1]][i-1];
root[u]=insert(root[fa],1,len,ask(val[u]),1);
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;if(v==fa)continue;
dfs(v,u);
}
}
int lca(int x,int y){
if(dep[x]<dep[y])swap(x,y);
for(int i=18;~i;i--)if(dep[f[x][i]]>=dep[y])x=f[x][i];
if(x==y)return x;
for(int i=18;~i;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
return f[x][0];
}
void solve(){
int lastans=0;
dfs(1,0);
while(m--){
int x,y,k;
scanf("%d%d%d",&x,&y,&k);
x=lastans^x;
int z=lca(x,y);
printf("%d\n",lastans=d[query(root[f[z][0]],root[z],root[x],root[y],1,len,k)]);
}
}
int main(){
read_and_parse();
solve();
return 0;
}
【SPOJ10628】Count on a tree的更多相关文章
- 【BZOJ2588】Count On a Tree(主席树)
[BZOJ2588]Count On a Tree(主席树) 题面 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第 ...
- 【SPOJ】Count On A Tree II(树上莫队)
[SPOJ]Count On A Tree II(树上莫队) 题面 洛谷 Vjudge 洛谷上有翻译啦 题解 如果不在树上就是一个很裸很裸的莫队 现在在树上,就是一个很裸很裸的树上莫队啦. #incl ...
- 【BZOJ-2588】Count on a tree 主席树 + 倍增
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 3749 Solved: 873[ ...
- 【BZOJ2558】Count on a tree
又是因为傻逼错误浪费了半天时间 原题: 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个 ...
- 【bzoj2588】Count on a tree
Portal -->bzoj2588 Solution 不行我一定要来挂这道题qwq很气愤qwq(其实还不是因为自己蠢..) 额首先说一下正解 如果这个问题放在序列上面的话..直接离散化一下然后 ...
- 【bzoj2588】Count on a tree 主席树
这题给人开了个新思路. 原本构造一个序列的主席树,是这个位置用上个位置的信息来省空间,树上的主席树是继承父亲的信息来省空间. 此题若带修改怎么办? 若对某个点的权值做修改,则这个点的子树都会受影响,想 ...
- 【BZOJ2588】Count on a tree 题解(主席树+LCA)
前言:其实就是主席树板子啦……只不过变成了树上的查询 -------------------------- 题目链接 题目大意:求树上$u$到$v$路径第$k$大数. 查询静态区间第$k$大肯定是用主 ...
- 【数据挖掘】分类之decision tree(转载)
[数据挖掘]分类之decision tree. 1. ID3 算法 ID3 算法是一种典型的决策树(decision tree)算法,C4.5, CART都是在其基础上发展而来.决策树的叶子节点表示类 ...
- 【LeetCode】二叉查找树 binary search tree(共14题)
链接:https://leetcode.com/tag/binary-search-tree/ [220]Contains Duplicate III (2019年4月20日) (好题) Given ...
随机推荐
- 新人入坑Redis必会的吐血总结
新人入坑Redis必会的吐血总结 一.什么是Redis Redis是一个使用C语言开发的开源的高性能的key-value存储系统,我们可以把它近似理解为Java Map.简单来讲,Redis是一种NO ...
- Webpack 2 视频教程 003 - Webpack 项目初始化
原文发表于我的技术博客 这是我免费发布的高质量超清「Webpack 2 视频教程」. Webpack 作为目前前端开发必备的框架,Webpack 发布了 2.0 版本,此视频就是基于 2.0 的版本讲 ...
- TRIO-basic指令--FLEXLINK
Type: Axis Command Syntax: FLEXLINK(base_dist, excite_dist, link_dist, base_in, base_out, excite_acc ...
- 2017BUAA软工第0次作业
第一部分:结缘计算机 1. 你为什么选择计算机专业?你认为你的条件如何?和这些博主比呢? 我在上大学之前,其实一直就没怎么考虑过自己以后想要选什么专业,只知道一个大致的方向一定是理工科.毕竟大学之前, ...
- String系列-----AbstractStringBuilder
1. AbstractStringBuilder是StringBuffer和StringBuilder的父类 package com.amazing.jdk.string_2017_12_31; im ...
- C++Primer中for(auto it=s.cbegin(); iter!=s.cend() && !it->empty(); ++it){ cout<<*it<<endl; }有错误
在C++ Primer 中文版 第五版的 98页 ,有这么一段代码 for(auto it=text.cbegin(); it!=text.cend() && !it->empt ...
- MyBatis自动生成Java/C#的Bean(Entity)的等价MYSQL实现函数
这是单元测试代码:TESTTITLECASE.sql SELECT TITLECASE('ABC_DEF_hgk') as BEANNAME FROM DUAL; SELECT TITLECASE(' ...
- js获取属性
js获取属性的方法: document.getElementById(); document.getElementsByTagname(); document.getElementsByClassna ...
- mxnet,theano与torch的简单比较
这篇文章我想来比较一下Theano和mxnet,Torch(Torch基本没用过,所以只能说一些直观的感觉).我主要从以下几个方面来计较它们: 1.学习框架的成本,接口设计等易用性方面. 三个框架的学 ...
- python slots
正常情况下,当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性.先定义class: >>> class Studen ...