BZOJ2588 主席树 + 树上差分
https://www.lydsy.com/JudgeOnline/problem.php?id=2588
题意:强制在线的询问树链权值第K小(无修)
这种类似于第K小的题,一般容易想到主席树,但是树链并不能不是一个按顺序的序列,使用树链剖分也不太容易维护几条链之间的第K小关系。
但是可以从主席树的前缀和思想入手,一般情况的主席树,查询的时候是query(R) - query(L - 1)来询问区间内的数值数量,在这一题里面,可以考虑到树上差分,从树根开始,以每一个点的父亲为前缀建立主席树。
然后查询的时候转变为query(u) + query(v) - query(lca(u,v,)) - query(fa(lca(u,v))) 就可以了。
#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);
#define Pri(x) printf("%d\n", x)
#define Prl(x) printf("%lld\n",x);
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
int read(){int x = ,f = ;char c = getchar();while (c<'' || c>''){if (c == '-') f = -;c = getchar();}
while (c >= ''&&c <= ''){x = x * + c - '';c = getchar();}return x*f;}
const double eps = 1e-;
const int maxn = 1e5 + ;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + ;
int N,M,K;
int val[maxn],Hash[maxn],tot,cnt,T[maxn];
struct Edge{
int to,next;
}edge[maxn * ];
int head[maxn],TOT;
void init(){
for(int i = ; i <= N ; i ++) head[i] = -;
TOT = tot = ;
}
void add(int u,int v){
edge[TOT].to = v;
edge[TOT].next = head[u];
head[u] = TOT++;
}
struct Tree{
int lt,rt,sum;
}tree[maxn * ];
void newnode(int &t){
t = ++tot;
tree[t].sum = ;
}
void Build(int &t,int l,int r){
newnode(t);
if(l == r) return;
int m = l + r >> ;
Build(tree[t].lt,l,m); Build(tree[t].rt,m + ,r);
}
void update(int &t,int pre,int l,int r,int p){
newnode(t);
tree[t] = tree[pre]; tree[t].sum++;
if(l == r) return;
int m = l + r >> ;
if(p <= m) update(tree[t].lt,tree[pre].lt,l,m,p);
else update(tree[t].rt,tree[pre].rt,m + ,r,p);
}
const int SP = ;
int fa[maxn][SP],dep[maxn];
void dfs(int u,int la){
int p = lower_bound(Hash + ,Hash + + cnt,val[u]) - Hash;
update(T[u],T[la],,cnt,p);
fa[u][] = la; dep[u] = dep[la] + ;
for(int i = ; i < SP; i ++) fa[u][i] = fa[fa[u][i - ]][i - ];
for(int i = head[u]; ~i ; i = edge[i].next){
int v = edge[i].to;
if(v == la) continue;
dfs(v,u);
}
}
int lca(int u,int v){
if(dep[u] < dep[v]) swap(u,v);
int t = dep[u] - dep[v];
for(int i = ; i < SP; i ++) if(t & ( << i)) u = fa[u][i];
for(int i = SP - ; i >= ; i --){
int uu = fa[u][i],vv = fa[v][i];
if(uu != vv){
u = uu; v = vv;
}
}
return u == v?u:fa[u][];
}
int query(int u,int v,int f,int ff,int l,int r,int k){
if(l >= r) return l;
int num = tree[tree[u].lt].sum + tree[tree[v].lt].sum - tree[tree[f].lt].sum - tree[tree[ff].lt].sum;
int m = l + r >> ;
if(k <= num) return query(tree[u].lt,tree[v].lt,tree[f].lt,tree[ff].lt,l,m,k);
else return query(tree[u].rt,tree[v].rt,tree[f].rt,tree[ff].rt,m + ,r,k - num);
}
int main(){
Sca2(N,M); init();
for(int i = ; i <= N ; i ++) val[i] = Hash[i] = read();
for(int i = ; i <= N - ; i ++){
int u = read(),v = read();
add(u,v); add(v,u);
}
sort(Hash + ,Hash + + N);
cnt = unique(Hash + ,Hash + + N) - Hash - ;
Build(T[],,cnt);
int root = ; dfs(root,);
int ans = ;
for(int i = ; i <= M; i ++){
int u = read() ^ ans,v = read(),k = read();
int l = lca(u,v);
//cout << u << " " << v << " " << l << " " << fa[l][0] << endl;
ans = Hash[query(T[u],T[v],T[l],T[fa[l][]],,cnt,k)];
Pri(ans);
}
return ;
}
BZOJ2588 主席树 + 树上差分的更多相关文章
- bzoj4448 [Scoi2015]情报传递 主席树+树上差分
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4448 题解 练习一下主席树的基础练习题找回感觉. 对于每一次询问,第一问显然随便做. 第二问的 ...
- [BZOJ 4771]七彩树(可持久化线段树+树上差分)
[BZOJ 4771]七彩树(可持久化线段树+树上差分) 题面 给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点.每个节点都被染上了某一种颜色,其中第i个节点的颜色为c[i].如果c[i] ...
- Codechef Sad Pairs——圆方树+虚树+树上差分
SADPAIRS 删点不连通,点双,圆方树 非割点:没有影响 割点:子树DP一下 有不同颜色,所以建立虚树 在圆方树上dfs时候 如果当前点是割点 1.统计当前颜色虚树上的不连通点对,树形DP即可 2 ...
- 洛谷P3168 [CQOI2015]任务查询系统 [主席树,差分]
题目传送门 任务查询系统 题目描述 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任 ...
- BZOJ4424/CF19E Fairy(dfs树+树上差分)
即删除一条边使图中不存在奇环.如果本身就是个二分图当然任意一条边都可以,先check一下.否则肯定要删除在所有奇环的交上的边. 考虑怎么找这些边.跑一遍dfs造出dfs树,找出返祖边构成的奇环.可以通 ...
- BZOJ3331 压力 (圆方树+树上差分)
题意 略 题解 求路径上的割点. 然后就直接圆方树上差分 CODE #include <bits/stdc++.h> using namespace std; inline void rd ...
- BZOJ3331 [BeiJing2013]压力[圆方树+树上差分]
圆方树新技能get.具体笔记见图连通性问题学习笔记. 这题求无向图的必经点,这个是一个固定套路:首先,一张连通的无向图中,每对点双和点双之间是以一个且仅一个割点连接起来的(如果超过一个就不能是割点了) ...
- P2664 树上颜色统计 点分治 虚树 树上差分 树上莫队
树上差分O(n)的做法 考虑每种颜色对每个点的贡献,如果对于每种颜色我们把当前颜色的点删除,那么原来的树就会分成几个子树,对于一个点,当前颜色在和他同子树的点的点对路径上是不会出现的.考虑到有多种颜色 ...
- FZU 2237 中位数 主席树 树上k大
#include <cstdio> #include <cstring> #include <queue> #include <set> #includ ...
随机推荐
- SQL server常用函数使用示例
select convert(nvarchar(10),id)+name from t //convert():数据类型转换,将“id”列转换为“nvarchar”. select cast(id a ...
- 从0开始的Python学习009参数
默认参数 对于参数有时候我们希望他是可选的,前面介绍了函数柯里化,当然还有其他的解决方案.如果不想给某些参数提供值的话,就让这写参数使用默认值.在函数定义的时候给参数赋值使用(参数,参数=值..... ...
- SQL 日期时间比较
原先的判断是 ae.首次受理时刻 >= '2015/12/1 0:00:00' AND ae.首次受理时刻 <= '2015/12/25 0:00:00' ,改为如下和时间变量比较 效率 ...
- 【iOS开发】Alamofire框架的使用一基本用法
Alamofire框架的使用一 —— 基本用法 对于使用Objective-C的开发者,一定非常熟悉AFNetworking这个网络框架.在苹果推出的Swift之后,AFNetworking的作者专门 ...
- Burpsuite 之intruder
首先工具:Burpsuite1.7,DVWA,火狐浏览器代理插件,火狐浏览器,密码字典(以下用Bp代指burpsuite) 启动Bp,启动DVWA,并打开本地代理功能 开启bp的拦截功能,并在dv ...
- mybatis配置文件说明(configuration)
1. xml结构(可查看mybatis-3-config.dtd) <!ELEMENT configuration (properties?, settings?, typeAliases?, ...
- A Deep Learning-Based System for Vulnerability Detection(二)
接着上一篇,这篇研究实验和结果. A.用于评估漏洞检测系统的指标 TP:为正确检测到漏洞的样本数量 FP:为检测到虚假漏洞样本的数量(误报) FN:为未检真实漏洞的样本数量(漏报) TN:未检测到漏洞 ...
- 前端面试必备的css盒子模型
今天同学发给了我一份前端基础的面试题,第一道便是对css盒子模型的理解,我看到的第一眼想到的是div,然后就...懵逼了,知其然不知其所以然.所以打算写一写盒子模型的概念理解啥的,如有写的不当的地方, ...
- Node、TS、Koa学习笔记
这样定义可以轻松拿到gender属性 这样定义,函数内显示没有gender 这种方法能得到gender但是函数内部没有gender 这种方式能到gender 但是在函数里施symbel属性,外部不能访 ...
- Zookeeper集群为什么要是单数
(原) 在zookeeper集群中,会有三种角色,leader. follower. observer分别对应着总统.议员.观察者. 半数以上投票通过:可以这样理解.客户端的增删改操作无论访问到了哪台 ...