洛谷P2633/bzoj2588 Count on a tree (主席树)
洛谷P2633/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
暴力自重。。。
来源:bzoj2588 Spoj10628.
Solution
bzoj题面传送门
无修改,树上路径查询k小值
k小值可以主席树解决,树上路径其实不用真的提出来,我们可以运用差分的思路,由于是点差,求出它的\(lca,\)那么\(ans=a[u]+a[v]-a[lca]-a[fa[lca]]\).
具体到这道题就是\(u\)的主席树\(+v\)的主席树\(-lca\)的主席树\(-fa[lca]\)的主席树
\(lca\)倍增求就可以了
Code
#include<bits/stdc++.h>
#define in(i) (i=read())
#define il extern inline
#define rg register
#define mid ((l+r)>>1)
#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)>(b)?(a):(b))
#define lol long long
using namespace std;
const int N=1e5+10;
int read() {
int ans=0, f=1; char i=getchar();
while (i<'0' || i>'9') {if(i=='-') f=-1; i=getchar();}
while (i>='0' && i<='9') ans=(ans<<1)+(ans<<3)+(i^48), i=getchar();
return ans*f;
}
int n,m,cur,num,tot,pre;
int head[N],nex[N<<1],to[N<<1];
int f[25][N],lg[N]={-1},dep[N];
int a[N],h[N],rt[N<<6];
struct Chair_Tree {
int l,r,v;
}t[N<<6];
void add(int a,int b) {
to[++cur]=b,nex[cur]=head[a],head[a]=cur;
to[++cur]=a,nex[cur]=head[b],head[b]=cur;
}
void insert(int &u,int l,int r,int pre,int p) {
t[u=++tot]=t[pre], t[u].v++;
if(l==r) return;
if(p<=mid) insert(t[u].l,l,mid,t[pre].l,p);
else insert(t[u].r,mid+1,r,t[pre].r,p);
}
int query(int a,int b,int c,int d,int l,int r,int k) {
int AQ=t[t[a].l].v+t[t[b].l].v-t[t[c].l].v-t[t[d].l].v;
if(l==r) return h[l];
if(k<=AQ) return query(t[a].l,t[b].l,t[c].l,t[d].l,l,mid,k);
else return query(t[a].r,t[b].r,t[c].r,t[d].r,mid+1,r,k-AQ);
}
void dfs(int u) {
a[u]=lower_bound(h+1,h+1+num,a[u])-h;
insert(rt[u],1,num,rt[f[0][u]],a[u]);
for (int i=head[u];i;i=nex[i]) {
if(to[i]==f[0][u]) continue;
dep[to[i]]=dep[u]+1, f[0][to[i]]=u;
dfs(to[i]);
}
}
void init() {
for (int i=1;i<=n;i++) lg[i]=lg[i>>1]+1;
for (int i=1;i<=lg[n];i++)
for (int j=1;j<=n;j++)
f[i][j]=f[i-1][f[i-1][j]];
}
int LCA(int a,int b) {
if(dep[a]>dep[b]) swap(a,b);
int s=dep[b]-dep[a];
for (int i=lg[s];i>=0;i--)
if(s>>i&1) b=f[i][b];
if(a==b) return a;
for (int i=lg[n];i>=0;i--) {
if(f[i][a]==f[i][b]) continue;
a=f[i][a], b=f[i][b];
}return f[0][a];
}
int main()
{
in(n), in(m);
for (int i=1;i<=n;i++) in(a[i]),h[i]=a[i];
sort(h+1,h+1+n); num=unique(h+1,h+1+n)-h-1;
for (int i=1,x,y;i<n;i++) in(x),in(y),add(x,y);
dep[1]=1, dfs(1), init();
for (int i=1,a,b,k;i<=m;i++) {
in(a),in(b),in(k),a^=pre;
int lca=LCA(a,b);
printf("%d\n",pre=query(rt[a],rt[b],rt[lca],rt[f[0][lca]],1,num,k));
}
}
洛谷P2633/bzoj2588 Count on a tree (主席树)的更多相关文章
- 【洛谷 P2633】 Count on a tree(主席树,树上差分)
题目链接 思维难度0 实现难度7 建出主席树后用两点的状态减去lca和lca父亲的状态,然后在新树上跑第\(k\)小 #include <cstdio> #include <cstr ...
- [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是上一个询问的答案,初始 ...
- 洛谷P2633 Count on a tree(主席树上树)
题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个 ...
- 洛谷 P2633 Count on a tree 主席树
在一棵树上,我们要求点 $(u,v)$ 之间路径的第$k$大数. 对于点 $i$ ,建立 $i$ 到根节点的一棵前缀主席树. 简单容斥后不难得出结果为$sumv[u]+sumv[v]−sumv[l ...
- 【洛谷2633】Count on a tree(树上主席树)
点此看题面 大致题意: 给你一棵树,每次问你两点之间第\(k\)小的点权,强制在线. 主席树 这种题目强制在线一般就是数据结构了. 而看到区间第\(k\)小,很容易就能想到主席树. 至少不会有人想到树 ...
- 【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[ ...
- P2633 Count on a tree(主席树)
题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个 ...
随机推荐
- MySQL-MMM方案
参考文档: 官方文档:http://mysql-mmm.org/mmm2:guide 本文对mmm方案做简单介绍,并做1个简单的验证. 一.MySQL-MMM方案 1. MMM方案简介 MMM(Mul ...
- Javascript 初学笔记
变量作用域 自 ES2015 起,JS 引入let 和 const 关键词定义变量的块作用域(Block Scope). var 仅支持全局作用域(Global Scope)和函数作用域(Functi ...
- NO.1:自学python之路------Hello world、判断、循环
引言 人工智能如今越来越贴近生活,在这里将记录我自学python与tensorflow的过程.编程使用IDE:visual studio 2017,python版本3.6.4,tensorflow版本 ...
- Tess4J -4.0.2- Linux 实践 [解决:Tess4J - Native library (linux-x86-64/libtesseract.so) not found in resource path]
[本文编写于2018年7月5日] Tess4J是Tesseract的Java JNA wrapper.本文介绍了在CentOS 7 操作系统中使用Tess4J的步骤及注意事项.在正式开始之前,先花一点 ...
- Immutable 常用API简介
本文主要整理了Immutable.js常用API的使用. Immutable 是什么? 关于Immutable的定义,官方文档是这样说的: Immutable data encourages pure ...
- USACO 1.2.3 Name That Number 命名那个数字(打开文件)
Description 在威斯康辛州牛大农场经营者之中,都习惯于请会计部门用连续数字给母牛打上烙印.但是,母牛用手机时并没感到这个系统的便利,它们更喜欢用它们喜欢的名字来呼叫它们的同伴,而不是用像这个 ...
- 模仿qq列表信息滑动删除效果
这个效果的完成主要分为两个部分 自定义view作为listview的列表项 一个view里面包括 显示头像,名字,消息内容等的contentView和滑动才能显示出来的删除,置顶的右边菜单menuVi ...
- 《我是一只IT小小鸟》 读书笔记
<我是一只IT小小鸟>讲述了IT人员的成长经历,邀请了许多名IT行业的职员,学生,研究生写了自己的亲身经历和人生感悟,以书中可以看到我国IT行业的快速进步,以及看到IT员在这条道路上的坎坷 ...
- Rsyslog初步学习
一.Rsyslog整体架构 Rsyslog消息流:输入模块——>预处理模块——>主队列——>过滤模块——>执行队列——>输出模块 1. 输入模块 输入模块是消息来源 2. ...
- centos系统下禁用笔记本触控板
最近把零几年的老爷笔记本拿出来用,使用windows系统实在太卡了,于是折腾安装上Centos系统了,但是在使用的过程中发现鼠标经常失效.使用了多种方法(比如:http://blog.csdn.net ...