对于每个节点维护这个节点到根的权值线段树

对于每个询问(x,y),这条路径上的线段树

tree[x]+tree[y]-tree[lca(x,y)]-tree[fa[lca(x,y)]]

 #include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=;
const int maxm=;
int n,m,tot,cnt,ind,sz,last;
int tmp[maxn],hash[maxn],g[maxn],v[maxn];
int num[maxn],pos[maxn],deep[maxn];
int sum[maxm],lch[maxm],rch[maxm];
int root[maxn];
int fa[maxn][];
struct Edge
{
int t,next;
}e[*maxn];
inline long long read()
{
long long x=,f=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
//二分查找离散化之后的x的下标
int find(int x)
{
int l=,r=tot;
while(l<=r)
{
int mid=(l+r)>>;
if(hash[mid]<x) l=mid+;
else if(hash[mid]==x) return mid;
else r=mid-;
}
return l;
}
void insert(int u,int v)
{
cnt++;
e[cnt].t=v;e[cnt].next=g[u];g[u]=cnt;
cnt++;
e[cnt].t=u;e[cnt].next=g[v];g[v]=cnt;
}
void dfs(int x)
{
ind++;num[ind]=x;pos[x]=ind;
for(int i=;i<=;i++)
if((<<i)<=deep[x]) fa[x][i]=fa[fa[x][i-]][i-];
else break;
for(int tmp=g[x];tmp;tmp=e[tmp].next)
{
if(fa[x][]!=e[tmp].t)
{
deep[e[tmp].t]=deep[x]+;
fa[e[tmp].t][]=x;
dfs(e[tmp].t);
}
}
}
void update(int l,int r,int x,int &y,int num)
{
y=++sz;
sum[y]=sum[x]+;
if(l==r) return;
lch[y]=lch[x];rch[y]=rch[x];
int mid=(l+r)>>;
if(num<=mid)
update(l,mid,lch[x],lch[y],num);
else update(mid+,r,rch[x],rch[y],num);
}
int lca(int x,int y)
{
if(deep[x]<deep[y]) swap(x,y);
int t=deep[x]-deep[y];
for(int i=;i<=;i++)
if((<<i)&t) x=fa[x][i];
for(int i=;i>=;i--)
if(fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
if(x==y) return x;
return fa[x][];
}
int query(int x,int y,int rk)
{
int a=x,b=y,c=lca(x,y),d=fa[c][];
a=root[pos[a]],b=root[pos[b]],c=root[pos[c]],d=root[pos[d]];
int l=,r=tot;
while(l<r)
{
int mid=(l+r)>>;
int tmp=sum[lch[a]]+sum[lch[b]]-sum[lch[c]]-sum[lch[d]];
if(tmp>=rk) r=mid,a=lch[a],b=lch[b],c=lch[c],d=lch[d];
else rk-=tmp,l=mid+,a=rch[a],b=rch[b],c=rch[c],d=rch[d];
}
return hash[l];
}
int main()
{
n=read();m=read();
for(int i=;i<=n;i++)
v[i]=read(),tmp[i]=v[i];
sort(tmp+,tmp+n+); //点权排序
hash[++tot]=tmp[];
for(int i=;i<=n;i++)
if(tmp[i]!=tmp[i-])
hash[++tot]=tmp[i];
//离散化
for(int i=;i<=n;i++) v[i]=find(v[i]);
//存位置,离散化
for(int i=;i<n;i++)
{
int u,v;
u=read();v=read();
insert(u,v);
}
dfs();
for(int i=;i<=n;i++)
{
int t=num[i]; //树上点权
update(,tot,root[pos[fa[t][]]],root[i],v[t]);//建立主席树
}
for(int i=;i<=m;i++)
{
int x=read(),y=read(),rk=read();
x^=last;
last=query(x,y,rk);
printf("%d",last);
if(i!=m) printf("\n");
}
return ;
}

BZOJ2588:LCA+主席树来实现树上两点之间第K大点权查询的更多相关文章

  1. 主席树学习笔记(静态区间第k大)

    题目背景 这是个非常经典的主席树入门题——静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个整数构成的序列,将对于指定的闭区间查询其区间内的第K小值. 输入输出 ...

  2. LCA+主席树 (求树上路径点权第k大)

      SPOJ 10628. Count on a tree (树上第k大,LCA+主席树) 10628. Count on a tree Problem code: COT You are given ...

  3. 【bzoj3123】[Sdoi2013]森林 倍增LCA+主席树+启发式合并

    题目描述 输入 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负 ...

  4. 少年,想学带修改主席树吗 | BZOJ1901 带修改区间第k小

    少年,想学带修改主席树吗 | BZOJ1901 带修改区间第k小 有一道题(BZOJ 1901)是这样的:n个数,m个询问,询问有两种:修改某个数/询问区间第k小. 不带修改的区间第k小用主席树很好写 ...

  5. 【bzoj2588/P2633】count on a tree —— LCA + 主席树

    (以下是luogu题面) 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问 ...

  6. spoj COT - Count on a tree (树上第K小 LCA+主席树)

    链接: https://www.spoj.com/problems/COT/en/ 思路: 首先看到求两点之前的第k小很容易想到用主席树去写,但是主席树处理的是线性结构,而这道题要求的是树形结构,我们 ...

  7. SPOJ 10628. Count on a tree (树上第k大,LCA+主席树)

    10628. Count on a tree Problem code: COT You are given a tree with N nodes.The tree nodes are number ...

  8. SPOJ 10628 Count on a tree(Tarjan离线LCA+主席树求树上第K小)

    COT - Count on a tree #tree You are given a tree with N nodes.The tree nodes are numbered from 1 to  ...

  9. SPOJ 10628 Count on a tree(Tarjan离线 | RMQ-ST在线求LCA+主席树求树上第K小)

    COT - Count on a tree #tree You are given a tree with N nodes.The tree nodes are numbered from 1 to  ...

随机推荐

  1. 团队开发NABCD

    团队成员介绍: 李青:绝对的技术控,团队中扮演“猪”的角色,勤干肯干,是整个团队的主心骨,课上紧跟老师的步伐,下课谨遵老师的指令,课堂效率高,他的编程格言“没有编不出来的程序,只有解决不了的bug”. ...

  2. 第四周作业——C语言自评

    1.你对自己的未来有什么规划?做了哪些准备?以目前的现状来说,希望至少能够掌握专业所要求的基本操作,然后一步步去深入.提升,毕业之后不会灰溜溜的一次次求职失败.目前更多的是利用闲暇时间补回过去老师同学 ...

  3. Java中按值传递与按引用传递的区别

    值传递:(形式参数类型是基本数据类型):方法调用时,实际参数把它的值传递给对应的形式参数,形式参数只是用实际参数的值初始化自己的存储单元内容,是两个不同的存储单元,所以方法执行中形式参数值的改变不影响 ...

  4. alpha8/10

    队名:Boy Next Door 燃尽图 晗(组长) 今日完成 和队友讨论alpha版的最终界面. 明日工作 确定alpha版既定功能的正常使用. 还剩下哪些任务 账号绑定功能以及账单信息的下载. 困 ...

  5. ORACLE公司传奇历史

    ORACLE公司传奇 ORACLE公司之起源 很难想象,ORACLE 公司的这一段传奇居然要从 IBM 公司开始. 1970年的6月,IBM 公司的研究员埃德加·考特 (Edgar Frank Cod ...

  6. 【beta】Scrum站立会议第3次....11.6

    小组名称:nice! 组长:李权 成员:于淼  刘芳芳韩媛媛 宫丽君 项目内容:约跑app(约吧) 时间:2016.11.6  12:00——12:30 地点:传媒西楼220室 本次对beta阶段的需 ...

  7. (转)Linux 命令--查看物理CPU个数、核数、逻辑CPU个数

    # 总核数 = 物理CPU个数 X 每颗物理CPU的核数 # 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数 # 查看物理CPU个数 cat /proc/cpuinfo| ...

  8. Django之contenttypes的应用

    Django contenttypes 应用 简介 contenttypes 是Django内置的一个应用,可以追踪项目中所有app和model的对应关系,并记录在ContentType表中. 每当我 ...

  9. webgl helloworld

    之前的webgl 初识1, 初识2 已经介绍了webgl的基本概念,工作原理. 没有理解的自己yy. 现呈上例子一枚 <!DOCTYPE html> <html lang=" ...

  10. javascript之彻底理解this

    彻底理解this,需要彻底理解函数 函数是复杂类型,存储在堆中.  函数是独立的, 对象中的方法只是对象中有个函数的引用 函数被调用时,调用者会像被调用者提供个上下文环境, 这个环境就是this 构造 ...