【BZOJ2588】Count On a Tree(主席树)
【BZOJ2588】Count On a Tree(主席树)
题面
题目描述
给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权。其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文。
输入格式:
第一行两个整数N,M。
第二行有N个整数,其中第i个整数表示点i的权值。
后面N-1行每行两个整数(x,y),表示点x到点y有一条边。
最后M行每行两个整数(u,v,k),表示一组询问。
输出格式:
M行,表示每个询问的答案。
输入输出样例
输入样例#1:
8 5
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 8
2 5 1
0 5 2
10 5 3
11 5 4
110 8 2
输出样例#1:
2
8
9
105
7
说明
HINT:
N,M<=100000
题解
链上的第k大->主席树
这题怎么搞得话
对于每一个节点建立一个线段树(显然开不下)
每个节点继承父节点再加上自己
主席树搞一下
查询的时候,跳\(u,v,lca,father(lca)\)四棵线段树就行了
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MAX 110000
#define lson (t[now].ls)
#define rson (t[now].rs)
inline int read()
{
int x=0,t=1;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
struct Line
{
int v,next;
}e[MAX<<1];
int h[MAX],cnt=1;
int n,m,sum;
int a[MAX],S[MAX],tot,z[MAX];
int rt[MAX];
struct Node
{
int ls,rs;
int v;
}t[MAX<<5];
inline void Add(int u,int v)
{
e[cnt]=(Line){v,h[u]};
h[u]=cnt++;
}
void Build(int &now,int l,int r)
{
now=++tot;
if(l==r)return;
int mid=(l+r)>>1;
Build(lson,l,mid);
Build(rson,mid+1,r);
}
void Update(int &now,int ff,int l,int r,int pos)
{
now=++tot;
t[now]=t[ff];
t[now].v++;
if(l==r)return;
int mid=(l+r)>>1;
if(pos<=mid)Update(lson,t[ff].ls,l,mid,pos);
else Update(rson,t[ff].rs,mid+1,r,pos);
}
int Query(int r1,int r2,int r3,int r4,int l,int r,int k)
{
if(l==r)return l;
int tmp=t[t[r1].ls].v+t[t[r2].ls].v-t[t[r3].ls].v-t[t[r4].ls].v;
int mid=(l+r)>>1;
if(k<=tmp)return Query(t[r1].ls,t[r2].ls,t[r3].ls,t[r4].ls,l,mid,k);
else return Query(t[r1].rs,t[r2].rs,t[r3].rs,t[r4].rs,mid+1,r,k-tmp);
}
int hson[MAX],fa[MAX],size[MAX],dep[MAX],top[MAX];
void dfs1(int u,int ff)
{
fa[u]=ff;size[u]=1;dep[u]=dep[ff]+1;
Update(rt[u],rt[ff],1,sum,a[u]);
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;
if(v==ff)continue;
dfs1(v,u);
size[u]+=size[v];
if(size[v]>size[hson[u]])hson[u]=v;
}
}
void dfs2(int u,int tp)
{
top[u]=tp;
if(hson[u])dfs2(hson[u],tp);
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;
if(v==fa[u]||v==hson[u])continue;
dfs2(v,v);
}
}
int LCA(int u,int v)
{
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])swap(u,v);
u=fa[top[u]];
}
return dep[u]<dep[v]?u:v;
}
int main()
{
n=sum=read();m=read();
for(int i=1;i<=n;++i)S[i]=a[i]=z[i]=read();
sort(&S[1],&S[n+1]);
sum=unique(&S[1],&S[sum+1])-S-1;
for(int i=1;i<=n;++i)a[i]=(lower_bound(&S[1],&S[sum+1],a[i])-S);
for(int i=1;i<n;++i)
{
int x=read(),y=read();
Add(x,y);Add(y,x);
}
Build(rt[0],1,sum);
dfs1(1,0);dfs2(1,1);
int lans=0;
while(m--)
{
int u=read()^lans,v=read(),k=read();
int lca=LCA(u,v);
printf("%d\n",lans=S[Query(rt[u],rt[v],rt[lca],rt[fa[lca]],1,sum,k)]);
}
return 0;
}
【BZOJ2588】Count On a Tree(主席树)的更多相关文章
- 洛谷P2633/bzoj2588 Count on a tree (主席树)
洛谷P2633/bzoj2588 Count on a tree 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K ...
- [bzoj2588][count on a tree] (主席树+lca)
Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...
- BZOJ2588:Count on a tree(主席树)
Description 给定一棵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 ...
- 【BZOJ-2588】Count on a tree 主席树 + 倍增
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 3749 Solved: 873[ ...
- 【bzoj2588】Count on a tree 主席树
这题给人开了个新思路. 原本构造一个序列的主席树,是这个位置用上个位置的信息来省空间,树上的主席树是继承父亲的信息来省空间. 此题若带修改怎么办? 若对某个点的权值做修改,则这个点的子树都会受影响,想 ...
- spoj cot: Count on a tree 主席树
10628. Count on a tree Problem code: COT You are given a tree with N nodes.The tree nodes are number ...
- Bzoj 2588: Spoj 10628. Count on a tree 主席树,离散化,可持久,倍增LCA
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2588 2588: Spoj 10628. Count on a tree Time Limit ...
- 洛谷P2633 Count on a tree(主席树上树)
题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个 ...
- SPOJ Count on a tree(主席树+LCA)
一.题目 COT - Count on a tree You are given a tree with N nodes. The tree nodes are numbered from 1 to ...
随机推荐
- Java线程池ThreadPoolExector的源码分析
前言:线程是我们在学习java过程中非常重要的也是绕不开的一个知识点,它的重要程度可以说是java的核心之一,线程具有不可轻视的作用,对于我们提高程序的运行效率.压榨CPU处理能力.多条线路同时运行等 ...
- 脚本实现centos7修改二块网卡名称并配置ip信息
#!/bin/bash interface1=`ls /sys/class/net|grep en|awk 'NR==1{print}'`interface2=`ls /sys/class/net|g ...
- Docker命令行安装Shipyard
1.下载自动部署Shell脚本 curl -sSL https://shipyard-project.com/deploy | bash -s 自动部署脚本中, 包括以下参数: ACTION: 表示可 ...
- httpd的三种模式比较
查看你的httpd使用了哪种模式: /usr/local/apache2/bin/httpd -V |grep 'Server MPM' 使用哪种模式,需要在编译的时候指定 --with-mpm=pr ...
- [记]Debian alias 设置, 不设置貌似有点不方便习惯
备忘录,记录下. 不知道 当前有那些 alias 的话 直接输入 alias ,回车就可以看到 alias 列表. 终端输入: vim ~/bash_aliases 然后输入: # some more ...
- 分享:Python中的位运算符
按位运算符是把数字看作二进制来进行计算的.用的不太多,简单了解. 下表中变量 a 为 60,b 为 13二进制格式如下: a = 0011 1100 b = 0000 1101 a&b = 0 ...
- Window Server 布署 WCF 服务 , 权限配置问题
起因: 客户服务器运行环境要求提高安全性,建议数据连接串采取 加密措施 ,或改用 Window 验证 连接数据库服务 .于是我们打算选择后着,将后台服务(Window Server)数据库连接串调整为 ...
- statement preparestatement CallableStatement
大家都知道Statement.PrepareStatement 和CallableStatement 对象,其实它们是interface,为什么JDBC2.0中要提供这三个对象呢?对于Statemen ...
- 深入js正则
开题 我们常常有正则的各种需求,普通的正则匹配符虽然够用,但是满足不了我们一些很奇怪的需求,所以我们需要更多的关于正则的知识点. 需求 比如我们有一个这样的需求,匹配出字符串里的第一个div标签:aa ...
- 03 JVM的垃圾回收机制
1.前言 理解JVM的垃圾回收机制(简称GC)有什么好处呢?作为一名软件开发者,满足自己的好奇心将是一个很好的理由,不过更重要的是,理解GC工作机制可以帮助你写出更好的Java程序. 在学习GC前,你 ...