主席树+LCA【p2633 (bzoj2588】 Count on a tree
Description
给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权。其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文。
Input
第一行两个整数N,M。
第二行有N个整数,其中第i个整数表示点i的权值。
后面N-1行每行两个整数(x,y),表示点x到点y有一条边。
最后M行每行两个整数(u,v,k),表示一组询问。
Output
M行,表示每个询问的答案。
虽然能看出来是一个树上套主席树的板子题.但是不知道公式的话,真的难写此题。
树上第\(k\)大问题与序列上的第\(k\)大问题不同.
树上第\(k\)大问题是在父亲节点的基础上新建树,而序列上的第\(k\)大问题则是在上一位置的基础上建树.
这里直接放公式(我也没搞清楚.qwq)
\]
因此直接在\(dfs\)的时候建树,并顺便预处理出来我们的倍增数组即可.
刚开始还以为要树剖套主席树,显然对我来说不可做 qwq.
代码
#include<cstdio>
#include<cctype>
#include<iostream>
#include<cstring>
#include<algorithm>
#define N 100008
#define R register
using namespace std;
inline void in(int &x)
{
int f=1;x=0;char s=getchar();
while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
while(isdigit(s)){x=x*10+s-'0';s=getchar();}
x*=f;
}
int n,m,new_n=1,head[N],tot;
int a[N],b[N],cnt,ans;
int root[N*35],lson[N*35],rson[N*35],sum[N*35];
struct cod{int u,v;}edge[N*2];
inline void add(int x,int y)
{
edge[++tot].u=head[x];
edge[tot].v=y;
head[x]=tot;
}
void build(int lastroot,int &nowroot,int l,int r,int pos)
{
nowroot=++cnt;
sum[nowroot]=sum[lastroot]+1;
lson[nowroot]=lson[lastroot];
rson[nowroot]=rson[lastroot];
if(l==r)return;
int mid=(l+r)>>1;
if(pos<=mid)build(lson[lastroot],lson[nowroot],l,mid,pos);
else build(rson[lastroot],rson[nowroot],mid+1,r,pos);
}
int query(int x,int y,int la,int lca_fa,int l,int r,int k)
{
if(l>=r)return l;
int tmp=sum[lson[x]]+sum[lson[y]]-sum[lson[la]]-sum[lson[lca_fa]];
int mid=(l+r)>>1;
if(tmp>=k) return query(lson[x],lson[y],lson[la],lson[lca_fa],l,mid,k);
else return query(rson[x],rson[y],rson[la],rson[lca_fa],mid+1,r,k-tmp);
}
int depth[N],fath[N][21];
void dfs1(int u,int fa)
{
depth[u]=depth[fa]+1;
build(root[fa],root[u],1,new_n,a[u]);
fath[u][0]=fa;
for(R int i=1;(1<<i)<=depth[u];i++)
fath[u][i]=fath[fath[u][i-1]][i-1];
for(R int i=head[u];i;i=edge[i].u)
{
if(edge[i].v==fa)continue;
dfs1(edge[i].v,u);
}
}
inline int lca(int x,int y)
{
if(depth[x]>depth[y])swap(x,y);
for(R int i=17;i>=0;i--)
if(depth[x]+(1<<i)<=depth[y])
y=fath[y][i];
if(x==y)return y;
for(R int i=17;i>=0;i--)
{
if(fath[x][i]==fath[y][i])continue;
x=fath[x][i],y=fath[y][i];
}
return fath[x][0];
}
int main()
{
in(n),in(m);
for(R int i=1;i<=n;i++)in(a[i]),b[i]=a[i];
sort(b+1,b+n+1);
for(R int i=2;i<=n;i++)
if(b[new_n]!=b[i])
b[++new_n]=b[i];
for(R int i=1;i<=n;i++)
a[i]=lower_bound(b+1,b+new_n+1,a[i])-b;
for(R int i=1,x,y;i<n;i++)
{
in(x),in(y);
add(x,y),add(y,x);
}
dfs1(1,0);
for(R int i=1,x,y,k,la;i<=m;i++)
{
in(x),in(y),in(k);
x^=ans;la=lca(x,y);
ans=b[query(root[x],root[y],root[la],root[fath[la][0]],1,new_n,k)];
printf("%d\n",ans);
}
}
主席树+LCA【p2633 (bzoj2588】 Count on a tree的更多相关文章
- 主席树+dfs SPOJ BZOJ2588 Count on a tree
这道题我由于智障错误导致一直错. 在树上建主席树,加上lca思想,很简单. #include<bits/stdc++.h> using namespace std; ; struct no ...
- 洛谷P2633/bzoj2588 Count on a tree (主席树)
洛谷P2633/bzoj2588 Count on a tree 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K ...
- Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式)
Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式) 题外话,这是我第40篇随笔,纪念一下.<( ̄︶ ̄)↗[GO!] 题意 是说有棵树,每个节点上 ...
- 【bzoj2588/P2633】count on a tree —— LCA + 主席树
(以下是luogu题面) 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问 ...
- 【BZOJ2588】Spoj 10628. Count on a tree 主席树+LCA
[BZOJ2588]Spoj 10628. Count on a tree Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lasta ...
- [bzoj2588][count on a tree] (主席树+lca)
Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...
- [Bzoj2588]Count on a tree(主席树+LCA)
Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...
- [BZOJ2588]Count on a tree(LCA+主席树)
题面 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个询问 ...
- 【BZOJ2588】Count on a tree 题解(主席树+LCA)
前言:其实就是主席树板子啦……只不过变成了树上的查询 -------------------------- 题目链接 题目大意:求树上$u$到$v$路径第$k$大数. 查询静态区间第$k$大肯定是用主 ...
随机推荐
- Charles 抓包发现自动跳转为https 问题梳理
今天遇到个有点意思的问题.特此记录. 业务场景: 做了一个页面,但是对外是挂载在京东主站上.如:www.jd.com/yifu/123456.html. 现场情况: 在本地/测试环境/预发环境中,每次 ...
- 安徽师大附中%你赛day6 T3 Hamsters [POI2010]CHO-Hamsters 解题报告
[POI2010]CHO-Hamsters 题意: 给出n个互不包含的字符串,要求你求出一个最短的字符串S,使得这n个字符串在S中总共至少出现m次,问S最短是多少? 范围: \(1 \le n \le ...
- 获取Parameter参数值,方便调试使用
#region #warning 调试使用,获取sql参数化,拼接出完整的sql语句,复制sql明文到mssql中运行 string debugSql = queryHelper.CommandTex ...
- The XOR Largest Pair [Trie]
描述 在给定的N个整数A1,A2--AN中选出两个进行xor运算,得到的结果最大是多少? 输入格式 第一行一个整数N,第二行N个整数A1-AN. 输出格式 一个整数表示答案. 样例输入 3 1 2 3 ...
- 问题总结——window平台下grunt\bower安装后无法运行的问题
一.问题: 安装grunt或者bower后,在cmd控制台运行grunt -version 或者 bower -v会出现:“xxx不是内部或外部命令,也不是可运行的程序或批处理文件”,
- JS 中 call 和 apply 的理解和使用
本文受到了知乎问题 如何理解和熟练运用js中的call及apply? 的启发. obj.call(thisObj, arg1, arg2, ...); obj.apply(thisObj, [arg1 ...
- Web.xml过滤器配置及执行顺序概念
第一个过滤器 @Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain ch ...
- 【HDU4405】Aeroplane chess [期望DP]
Aeroplane chess Time Limit: 1 Sec Memory Limit: 32 MB[Submit][Stataus][Discuss] Description Hzz lov ...
- [BZOJ1005]Prufer数列+排列组合
一棵树的Prufer数列 每次在剩下的树中找到标号最小的叶子节点(对于无根树而言即是度数为1的节点),删去. 同时将其父节点(即与其相连的唯一点)加入Prufer数列当中. 一个Prufer数列所对应 ...
- bzoj 1876 高精
首先我们知道,对于两个数a,b,他们的gcd情况有如下形式的讨论 当a为奇数,b为偶数的时候gcd(a,b)=gcd(a div 2,b) 当b为奇数,a为偶数的时候gcd(a,b)=gcd(a,b ...