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 ...
随机推荐
- android入门 — Activity生命周期
Activity总共有7个回调方法,代表着不同的生命周期的环节. 1.onCreate() 在活动第一次被创建的时候调用.在这个方法中需要完成活动的初始化操作,比如说加载布局.绑定事件等. 2.onS ...
- 第一章 JavaScript简介
DOM级别 DOM1:映射文档的结构 DOM2: DOM视图,定义了跟踪不同文档视图的接口(例如CSS应用前后的文档) DOM事件,定义了事件和事件处理的接口 DOM样式,定义了基于CSS为元素应用样 ...
- 在.net项目中使用Consul
1.创建.net core web程序并运行 2.在Consul中注册该服务 Consul支持两种服务注册的方式,一种是通过Consul的服务注册HTTP API,由服务自身在启动后调用API注册自己 ...
- WebService(三)
JAX-WS简单使用示例: 1.服务端 package com.rong.service; import javax.jws.WebMethod; import javax.jws.WebParam; ...
- 2."结对项目"的心得体会
上个星期,老师给我们布置了个课堂小作业: 某公司程序员二柱的小孩上了小学二年级,老师让家长每天出30道(100以内)四则运算题目给小学生做.二柱立马就想到写一个小程序来做这件事. 这个事情可以用很 ...
- 【Leetcode】771. Jewels and Stones
(找了leetcode上最简单的一个题来找一下存在感) You're given strings J representing the types of stones that are jewels, ...
- PHP关于传众多参数还是传上下文对象的性能测试
在开发微信公众平台平台的过程中,有这么几个参数总是需要传来传去,$userOpenId,$message,$time. 在整个程序的运行过程中,为了函数方便的处理,将这三个变量一直放在参数列表里.关于 ...
- php面试必知必会常见问题
1 说出常用的10个数组方法 我觉得数组比较最能体现PHP基础语法的一个数据结构了,下面给大家列一下常用的10个关于操作数组的函数 in_array(判断数组中是否有某个元素) implode(将数组 ...
- 【ASP.NET Core 】ASP.NET Core 源码学习之 Logging[1]:Introduction
在ASP.NET 4.X中,我们通常使用 log4net, NLog 等来记录日志,但是当我们引用的一些第三方类库使用不同的日志框架时,就比较混乱了.而在 ASP.Net Core 中内置了日志系统, ...
- iOS-开发者账号与证书
0.开发者账号的申请 1.iOS-证书相关 2.iOS-证书申请 3.iOS-APNS证书申请与使用 4.iOS-App发布证书的申请与使用