BZOJ2588:LCA+主席树来实现树上两点之间第K大点权查询
对于每个节点维护这个节点到根的权值线段树
对于每个询问(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大点权查询的更多相关文章
- 主席树学习笔记(静态区间第k大)
题目背景 这是个非常经典的主席树入门题——静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个整数构成的序列,将对于指定的闭区间查询其区间内的第K小值. 输入输出 ...
- LCA+主席树 (求树上路径点权第k大)
SPOJ 10628. Count on a tree (树上第k大,LCA+主席树) 10628. Count on a tree Problem code: COT You are given ...
- 【bzoj3123】[Sdoi2013]森林 倍增LCA+主席树+启发式合并
题目描述 输入 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负 ...
- 少年,想学带修改主席树吗 | BZOJ1901 带修改区间第k小
少年,想学带修改主席树吗 | BZOJ1901 带修改区间第k小 有一道题(BZOJ 1901)是这样的:n个数,m个询问,询问有两种:修改某个数/询问区间第k小. 不带修改的区间第k小用主席树很好写 ...
- 【bzoj2588/P2633】count on a tree —— LCA + 主席树
(以下是luogu题面) 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问 ...
- spoj COT - Count on a tree (树上第K小 LCA+主席树)
链接: https://www.spoj.com/problems/COT/en/ 思路: 首先看到求两点之前的第k小很容易想到用主席树去写,但是主席树处理的是线性结构,而这道题要求的是树形结构,我们 ...
- 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 ...
- 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 ...
- 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 ...
随机推荐
- HDU 5203 Rikka with wood sticks 分类讨论
题目链接: hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5203 bc(chinese):http://bestcoder.hdu.edu.cn/con ...
- java 抽象类&接口
1,抽象类中有构造函数吗? 有,用于给子类对象进行初始化. 2,抽象关键字不可以和那些关键字共存? private 不行 static 不行 final 不行 final关键字: 1,fina ...
- PAT 甲级 1027 Colors in Mars
https://pintia.cn/problem-sets/994805342720868352/problems/994805470349344768 People in Mars represe ...
- php opensll加解密类
<?php $pri = "-----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQCzJc4RrAqaH2Es02XQ91Cqp/JK0yX893 ...
- ASP.NET前后端分离框架
- oracle 绝对值小于1的数值显示小数点前面的0
SELECT DECODE(TRUNC(-.98),0,REPLACE(TO_CHAR(-.98), '.', '0.'),TO_CHAR(-.98))FROM DUAL;
- ThinkPHP的调用css,js和图片的路径
按网上的说法,在根目录下建了一个Public目录,把css,js和图片放到Public目录下,然后用__PUBLIC__/...或__ROOT__/Public/...调用.但是发现无论如何改路径都无 ...
- 第73天:jQuery基本动画总结
一.DOM对象跟jQuery对象相互转换 jQuery对象转换成DOM对象: 方式一:$(“#btn”)[0] 方式二:$(“#btn”).get(0) DOM对象转换成jQuery对象: $(doc ...
- [Code Festival 2017 qual A] C: Palindromic Matrix
题意 给出一个小写字母组成的字符矩阵,问能否通过重排其中的字符使得每行每列都是回文串. 分析 简化版:给出一个字符串,问能否通过重排其中的字符使得它是回文串.那么如果字符串长度为偶数,就需要a到z的个 ...
- APIO/CTSC2017游记
5.10开坑,别问我为啥今天才开始写,前几天玩得太开心了233 5.7 坐火车坐火车,坐地铁坐地铁.其实是第一次坐地铁233.解锁了在地铁上双手玩手机不扶东西站立的姿势? 全程烧流量上QQ,拜大佬约面 ...