BZOJ 3551: [ONTAK2010]Peaks加强版 Kruskal重构树+dfs序+主席树+倍增
建出来 $Kruskal$ 重构树.
将询问点向上跳到深度最小,且合法的节点上.
那么,得益于重构树优美的性质,这个最终跳到的点为根的所有子节点都可以与询问点互达.
对于子树中求点权第 $k$ 大的问题,直接对 $dfs$ 序建主席树即可.
#include <cstdio>
#include <algorithm>
#define N 200005
#define M 500002
#define inf 1000000000
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
namespace IO {
char *p1,*p2,buf[100000];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int rd() {int x=0; char c=nc(); while(c<48) c=nc(); while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc(); return x;}
};
int h[N],rt[N],n,m,Q;
struct Edge {
int u,v,c;
}e[M];
bool cmp(Edge a,Edge b) {
return a.c<b.c;
}
namespace seg {
#define ls t[now].lson
#define rs t[now].rson
struct Node {
int lson,rson,sum;
}t[N*30];
int tot;
void update(int pre,int &now,int l,int r,int p) {
now=++tot;
t[now]=t[pre];
++t[now].sum;
if(l==r) return;
int mid=(l+r)>>1;
if(p<=mid) update(t[pre].lson,ls,l,mid,p);
else update(t[pre].rson,rs,mid+1,r,p);
}
int kth(int rt1,int rt2,int l,int r,int k) {
if(t[rt2].sum-t[rt1].sum==0) return 0;
if(l==r) return l;
int mid=(l+r)>>1,rsize=t[t[rt2].rson].sum-t[t[rt1].rson].sum;
if(k<=rsize) return kth(t[rt1].rson,t[rt2].rson,mid+1,r,k);
else return kth(t[rt1].lson,t[rt2].lson,l,mid,k-rsize);
}
#undef ls
#undef rs
};
namespace tree {
int tot,edges,tim;
int p[N],maxv[N],hd[N],to[N],nex[N],fa[22][N],F[22][N],dfn[N],size[N],dot[N];
void init() {
for(int i=1;i<=n;++i) p[i]=i;
}
int find(int x) {
return p[x]==x?x:p[x]=find(p[x]);
}
void addedge(int u,int v) {
nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;
}
void dfs(int u,int ff) {
int i,j;
dfn[u]=++tim,dot[tim]=u,size[u]=1;
fa[0][u]=ff, F[0][u]=max(maxv[u],maxv[ff]);
for(i=1;i<=20;++i) {
fa[i][u]=fa[i-1][fa[i-1][u]];
F[i][u]=max(F[i-1][u], F[i-1][fa[i-1][u]]);
}
for(i=hd[u];i;i=nex[i]) dfs(to[i],u),size[u]+=size[to[i]];
}
// 找到最后一个小的等于 k 的点
int get(int x,int k) {
for(int i=20;i>=0;--i)
if(fa[i][x]&&F[i][x]<=k) x=fa[i][x];
return x;
}
void build() {
init();
sort(e+1,e+1+m,cmp);
tot=n;
for(int i=1;i<=m;++i) {
int u=e[i].u,v=e[i].v,c=e[i].c,x,y;
x=find(u),y=find(v);
if(x!=y) {
++tot;
p[x]=p[y]=p[tot]=tot;
maxv[tot]=c;
addedge(tot,x),addedge(tot,y);
}
}
dfs(tot,0);
for(int i=1;i<=tim;++i) {
if(dot[i]>n) rt[i]=rt[i-1];
else seg::update(rt[i-1],rt[i],0,inf,h[dot[i]]);
// printf("%d %d\n",i,h[dot[i]]);
}
}
};
int main() {
int i,j;
// setIO("input");
using namespace IO;
n=rd(),m=rd(),Q=rd();
for(i=1;i<=n;++i) h[i]=rd();
for(i=1;i<=m;++i) e[i].u=rd(),e[i].v=rd(),e[i].c=rd();
tree::build();
int lastans=0;
for(i=1;i<=Q;++i) {
int v,x,k;
v=rd(),x=rd(),k=rd();
if(lastans!=-1) {
v^=lastans;
x^=lastans;
k^=lastans;
}
int p=tree::get(v,x);
int l=tree::dfn[p], r=tree::dfn[p]+tree::size[p]-1;
int re=seg::kth(rt[l-1],rt[r],0,inf,k);
printf("%d\n",re?re:-1);
lastans=re;
}
return 0;
}
BZOJ 3551: [ONTAK2010]Peaks加强版 Kruskal重构树+dfs序+主席树+倍增的更多相关文章
- BZOJ 3551: [ONTAK2010]Peaks加强版 [Kruskal重构树 dfs序 主席树]
3551: [ONTAK2010]Peaks加强版 题意:带权图,多组询问与一个点通过边权\(\le lim\)的边连通的点中点权k大值,强制在线 PoPoQQQ大爷题解传送门 说一下感受: 容易发现 ...
- BZOJ.3551.[ONTAK2010]Peaks加强版(Kruskal重构树 主席树)
题目链接 \(Description\) 有n个座山,其高度为hi.有m条带权双向边连接某些山.多次询问,每次询问从v出发 只经过边权<=x的边 所能到达的山中,第K高的是多少. 强制在线. \ ...
- BZOJ3551 ONTAK2010Peaks加强版(kruskal重构树+dfs序+主席树)
kruskal重构树本质就是给并查集显式建树来替代可持久化并查集.将边按困难度从小到大排序后建出该树,按dfs序建主席树即可.查询时跳到深度最浅的满足在该重要度下已被合并的点,在子树内查询第k大. # ...
- 【BZOJ-3545&3551】Peaks&加强版 Kruskal重构树 + 主席树 + DFS序 + 倍增
3545: [ONTAK2010]Peaks Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1202 Solved: 321[Submit][Sta ...
- [BZOJ3551][ONTAK2010]Peaks(加强版)(Kruskal重构树,主席树)
3551: [ONTAK2010]Peaks加强版 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 2438 Solved: 763[Submit][ ...
- 【BZOJ 3551】[ONTAK2010] Peaks加强版 Kruskal重构树+树上倍增+主席树
这题真刺激...... I.关于Kruskal重构树,我只能开门了,不过补充一下那玩意还是一棵满二叉树.(看一下内容之前请先进门坐一坐) II.原来只是用树上倍增求Lca,但其实树上倍增是一种方法,L ...
- 2018.09.30 bzoj3551:Peaks加强版(dfs序+主席树+倍增+kruskal重构树)
传送门 一道考察比较全面的题. 这道题又用到了熟悉的kruskal+倍增来查找询问区间的方法. 查到询问的子树之后就可以用dfs序+主席树统计答案了. 代码: #include<bits/std ...
- bzoj 3551 [ONTAK2010]Peaks加强版(kruskal,主席树,dfs序)
Description [题目描述]同3545 Input 第一行三个数N,M,Q. 第二行N个数,第i个数为h_i 接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径. 接下来 ...
- BZOJ3551: [ONTAK2010]Peaks加强版【Kruskal重构树】【主席树】
重要的事情说三遍 不保证图联通 不保证图联通 不保证图联通 那些和我一样认为重构树是点数的童鞋是要GG Description [题目描述]同3545 Input 第一行三个数N,M,Q. 第二行N个 ...
随机推荐
- 2019牛客暑期多校训练营(第三场)- F Planting Trees
题目链接:https://ac.nowcoder.com/acm/contest/883/F 题意:给定n×n的矩阵,求最大子矩阵使得子矩阵中最大值和最小值的差值<=M. 思路:先看数据大小,注 ...
- MyBatis 安装和配置
在这里我们使用 MyBatis 开发一个简单的 Java 项目(默认你已安装JDK和MySQL及会使用Maven的基本操作),可以与上一篇通过底层操作数据进行比较 1.新建表 students,插入数 ...
- 什么是云数据库RDS PPAS 版
云数据库PPAS版,是阿里云与EnterpriseDB公司合作基于PostgreSQL高度兼容Oracle语法的数据库服务,为用户提供易于操作的迁移工具,兼容范围涵盖:PL/SQL.数据类型.高级函数 ...
- UOJ46 玄学
题目 一个比较自然的想法是线段树维护二进制分组. 因为我们询问的是一段连续的操作的积,所以我们可以建一棵线段树,每个节点存储当前区间各个操作的积. 这里的操作的积指的是把一系列操作做完之后区间每个位置 ...
- Windows 系统安装 Docker
详细方法参见官方文档. Win10 家庭版 安装Toolbox Win10 家庭版由于功能限制,不能直接安装 Docker for Windows, 需要使用 Toolbox 的形式进行安装. 确认版 ...
- mysql 相关文章
<58到家MySQL军规升级版> <数据库索引,到底是什么做的?> <MyISAM与InnoDB的索引差异究竟是啥?> <InnoDB,为何并发如此之高?&g ...
- 网络信息统计netstat|ss|ip
1:netstate[弃用] netstat的作用: 需求 原命令 新命令 1:网络连接 netstat -a ss 2:路由表 netstat -r ip route 3:统计接口 netstat ...
- Jquery table相关--工时系统
1.jquery 的弹出对话框,单击事件之后 if (confirm("确定要删除?")) { // //点击确定后操作 } 2.对某个table中的checkbox是否被选中的遍 ...
- 小P的架构生活(下)
小L强烈建议团队使用微服务,并极力推荐了前公司用的一套分布式事务解决方案. 小P经过反复思考查证并做了大量的尝试后,辨证地对微服务架构做了如下分析: 为什么要用微服务,微服务带来了哪些好处? 1.减少 ...
- TP-Link 路由器 如何在现有的环境中改善无线信号传输质量
http://service.tp-link.com.cn/detail_article_346.html