题目大意:给定一棵 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的更多相关文章

  1. 【BZOJ2588】Count On a Tree(主席树)

    [BZOJ2588]Count On a Tree(主席树) 题面 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第 ...

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

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

  3. 【BZOJ-2588】Count on a tree 主席树 + 倍增

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 3749  Solved: 873[ ...

  4. 【BZOJ2558】Count on a tree

    又是因为傻逼错误浪费了半天时间 原题: 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个 ...

  5. 【bzoj2588】Count on a tree

    Portal -->bzoj2588 Solution 不行我一定要来挂这道题qwq很气愤qwq(其实还不是因为自己蠢..) 额首先说一下正解 如果这个问题放在序列上面的话..直接离散化一下然后 ...

  6. 【bzoj2588】Count on a tree 主席树

    这题给人开了个新思路. 原本构造一个序列的主席树,是这个位置用上个位置的信息来省空间,树上的主席树是继承父亲的信息来省空间. 此题若带修改怎么办? 若对某个点的权值做修改,则这个点的子树都会受影响,想 ...

  7. 【BZOJ2588】Count on a tree 题解(主席树+LCA)

    前言:其实就是主席树板子啦……只不过变成了树上的查询 -------------------------- 题目链接 题目大意:求树上$u$到$v$路径第$k$大数. 查询静态区间第$k$大肯定是用主 ...

  8. 【数据挖掘】分类之decision tree(转载)

    [数据挖掘]分类之decision tree. 1. ID3 算法 ID3 算法是一种典型的决策树(decision tree)算法,C4.5, CART都是在其基础上发展而来.决策树的叶子节点表示类 ...

  9. 【LeetCode】二叉查找树 binary search tree(共14题)

    链接:https://leetcode.com/tag/binary-search-tree/ [220]Contains Duplicate III (2019年4月20日) (好题) Given ...

随机推荐

  1. RabbitMQ在特来电的深度应用

    特来电是一个互联网公司,而且是技术领先的互联网公司.互联网公司的标配是什么?答案就是缓存+MQ.没错,您没看错,就是MQ--消息队列,我们今天要讨论的RabbitMQ就是消息队列中功能非常强大的一种. ...

  2. Windows 10 中 VMware 要求禁用 Device Guard 问题

    今天在打开虚拟机的时候,突然出现下面这个错误.网上给了很多教程,基本上都是禁用 Device Guard 和关闭 Hyper-v,博主按照其方法操作,依旧出现下面错误.后来经过不懈努力,终于找到解决办 ...

  3. spring-session-data-redis包冲突

    包冲突 spring 的包很容易冲突, 因为写软件的人在兼容性上处理的不够,一般不检测重复加载. spring-session-data-redis 引用后, 一定要把 spring-session ...

  4. Python-注册登陆-20

    username = input('请输入你要注册的用户名:') password = input('请输入你要注册的密码:') with open('list_of_info',mode='w',e ...

  5. “数学口袋精灵”App的第三个Sprint计划----开发日记

    一.现状 上一阶段基本完成一个小游戏,游戏具有:随机产生算式,判断对错功能.通过轻快的背景音乐,音效,给玩家提供一个良好的氛围.   二.任务认领 完成界面,基本功能后的后续任务: 冯美欣:设计&qu ...

  6. chrome启用flash不询问

    69版本之后 打开 chrome://flags/#enable-ephemeral-flash-permission 把它从Default改为Disabled 重新打开Chrome,进入 chrom ...

  7. JQuery Cross Domain Ajax(jsonp)

    http://www.pureexample.com/jquery/cross-domain-ajax.html http://www.pureexample.com/ExampleTesterII- ...

  8. Tomcat7解决java.lang.OutOfMemoryError: PermGen space

    上述两参数,可根据实际情况,逐渐调大.

  9. Docker Dockerfile指令

    Docker 可以通过 Dockerfile 的内容来自动构建镜像.Dockerfile 是一个包含创建镜像所有命令的文本文件,通过docker build命令可以根据 Dockerfile 的内容构 ...

  10. python对redis的常用操作 上 (对列表、字符串、散列结构操作)

    这里的一切讨论均基于python的redis-py库. 安装使用: pip install redis 然后去获取一个redis客户端: redis_conn = redis.Redis(host=R ...