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

对于每个询问(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. 【Alpha】阶段第五次Scrum Meeting

    [Alpha]阶段第五次Scrum Meeting 工作情况 团队成员 今日已完成任务 明日待完成任务 刘峻辰 增加课程接口 增加教师接口 赵智源 整合前端进行部署 构建后端测试点测试框架 肖萌威 编 ...

  2. 总结在Visual Studio Code运行node.js项目遇到的问题

    一.cannot find module “lodash” 项目运行时出现以下错误: Error: Cannot find module 'lodash' at Function.Module._re ...

  3. Java final用法

    //继承弊端:打破了封装性. /* final关键字: 1,final是一个修饰符,可以修饰类,方法,变量. 2,final修饰的类不可以被继承. 3,final修饰的方法不可以被覆盖. 4,fina ...

  4. TCP系列41—拥塞控制—4、Linux中的慢启动和拥塞避免(一)

    一.Linux中的慢启动和拥塞避免 Linux中采用了Google论文的建议把IW初始化成了10了.在linux中一般有三种场景会触发慢启动过程 1.连接初始建立发送数据的时候,此时cwnd初始化为1 ...

  5. [CB] Windows10为什么质量变差 bug越来越多

    在 Windows 10 发布之后,微软转向了软件即服务模式,每半年释出一个新版本,通过增加更新频率将新的特性不断推送给用户. 在以前,微软产品发布周期是两到三年,其开发流程分成多个阶段:设计和策划. ...

  6. Centos上Apache重启,mysql重启,nginx重启方法

    转载:http://www.3lian.com/edu/2012/04-01/24278.html Centos上Apache重启,mysql重启, nginx 重启方法 1.重启 apache se ...

  7. php 计算本周星期一、本月第一天 本月最后一天 下个月第一天

    本周一echo date('Y-m-d',(time()-((date('w')==0?7:date('w'))-1)*24*3600)); //w为星期几的数字形式,这里0为周日 本周日 echo  ...

  8. eclipse错误:Access restriction: The type 'BASE64Decoder' is not API

    Access restriction: The type ‘BASE64Decoder’ is not API (restriction on required library ‘D:\java\jd ...

  9. DjangoORM创建表结构以及生成数据库结构

    1. ORM的两种 DB first: 创建表结构--根据表结构生成类-----根据类来操作数据库 Code first: 先写代码------再写类----执行命令(一个类生成一个表)当前主流的用法 ...

  10. BZOJ1367 [Baltic2004]sequence 【左偏树】

    题目链接 BZOJ1367 题解 又是一道神题,, 我们考虑一些简单的情况: 我们先假设\(b_i\)单调不降,而不是递增 对于递增序列\(\{a_i\}\),显然答案\(\{b_i\}\)满足\(b ...