【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 ...
随机推荐
- 批量实现多台服务器之间ssh无密码登录的相互信任关系
最近IDC上架了一批hadoop大数据业务服务器,由于集群环境需要在这些服务器之间实现ssh无密码登录的相互信任关系.具体的实现思路:在其中的任一台服务器上通过"ssh-keygen -t ...
- GlusterFS分布式存储集群部署记录-相关补充
接着上一篇Centos7下GlusterFS分布式存储集群环境部署记录文档,继续做一些补充记录,希望能加深对GlusterFS存储操作的理解和熟悉度. ======================== ...
- Linux下rsyslog日志收集服务环境部署记录
rsyslog 可以理解为多线程增强版的syslog. 在syslog的基础上扩展了很多其他功能,如数据库支持(MySQL.PostgreSQL.Oracle等).日志内容筛选.定义日志格式模板等.目 ...
- linux及安全第四周总结
学习内容:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用 一.用户态.内核态 权限分级——为了系统本身更稳定,使系统不宜崩溃.(并不是所有程序员缩写的代码都很健壮!!) x86 CP ...
- 猫咪记单词Beta版使用说明
猫咪记单词Beta版使用说明 一.项目背景 英语四级考试.六级考试.托福.雅思等英语方面的考试是现在大学生必须面对的问题.同时因为学生对手机的使用越来越频繁,而且仅仅通过书本背诵单词又比较无聊坚持的时 ...
- JS 字符串转换为number
// '+ "42"' --> + 加上数字字符串可转换成数值 console.log(typeof (+ "42")); // 输出为 number
- 小学生四则运算App实验成果
组名:会飞的小鸟 组员:徐侃 陈志棚 罗伟业 刘芮熔 成员分工: ①刘芮熔:设置安卓包.界面的代码,界面的排序. ②陈志棚:加减乘除的判断异常处理,例如除数不能为零的异常处理等问题. ③徐侃 ...
- 小学四则运算APP 第一阶段冲刺
需求分析 1.相关系统分析员向用户初步了解需求,然后用word列出要开发的系统的大功能模块,每个大功能模块有哪些小功能模块,对于有些需求比较明确相关的界面时,在这一步里面可以初步定义好少量的界面.[1 ...
- 微信小程序navigator
如果是小程序自身页面的跳转 <navigator open-type="navigate" target="self" url="target ...
- ecshop2.73修改密码方法|ecshop2.73修改密码方法
ecshop2.73修改密码方法|ecshop2.73修改密码方法 ECSHOP教程/ ecshop教程网(www.ecshop119.com) 2012-09-09 ecshop2.73正式版后 ...