建出来 $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序+主席树+倍增的更多相关文章

  1. BZOJ 3551: [ONTAK2010]Peaks加强版 [Kruskal重构树 dfs序 主席树]

    3551: [ONTAK2010]Peaks加强版 题意:带权图,多组询问与一个点通过边权\(\le lim\)的边连通的点中点权k大值,强制在线 PoPoQQQ大爷题解传送门 说一下感受: 容易发现 ...

  2. BZOJ.3551.[ONTAK2010]Peaks加强版(Kruskal重构树 主席树)

    题目链接 \(Description\) 有n个座山,其高度为hi.有m条带权双向边连接某些山.多次询问,每次询问从v出发 只经过边权<=x的边 所能到达的山中,第K高的是多少. 强制在线. \ ...

  3. BZOJ3551 ONTAK2010Peaks加强版(kruskal重构树+dfs序+主席树)

    kruskal重构树本质就是给并查集显式建树来替代可持久化并查集.将边按困难度从小到大排序后建出该树,按dfs序建主席树即可.查询时跳到深度最浅的满足在该重要度下已被合并的点,在子树内查询第k大. # ...

  4. 【BZOJ-3545&3551】Peaks&加强版 Kruskal重构树 + 主席树 + DFS序 + 倍增

    3545: [ONTAK2010]Peaks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1202  Solved: 321[Submit][Sta ...

  5. [BZOJ3551][ONTAK2010]Peaks(加强版)(Kruskal重构树,主席树)

    3551: [ONTAK2010]Peaks加强版 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2438  Solved: 763[Submit][ ...

  6. 【BZOJ 3551】[ONTAK2010] Peaks加强版 Kruskal重构树+树上倍增+主席树

    这题真刺激...... I.关于Kruskal重构树,我只能开门了,不过补充一下那玩意还是一棵满二叉树.(看一下内容之前请先进门坐一坐) II.原来只是用树上倍增求Lca,但其实树上倍增是一种方法,L ...

  7. 2018.09.30 bzoj3551:Peaks加强版(dfs序+主席树+倍增+kruskal重构树)

    传送门 一道考察比较全面的题. 这道题又用到了熟悉的kruskal+倍增来查找询问区间的方法. 查到询问的子树之后就可以用dfs序+主席树统计答案了. 代码: #include<bits/std ...

  8. bzoj 3551 [ONTAK2010]Peaks加强版(kruskal,主席树,dfs序)

    Description [题目描述]同3545 Input 第一行三个数N,M,Q. 第二行N个数,第i个数为h_i 接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径. 接下来 ...

  9. BZOJ3551: [ONTAK2010]Peaks加强版【Kruskal重构树】【主席树】

    重要的事情说三遍 不保证图联通 不保证图联通 不保证图联通 那些和我一样认为重构树是点数的童鞋是要GG Description [题目描述]同3545 Input 第一行三个数N,M,Q. 第二行N个 ...

随机推荐

  1. 2019牛客暑期多校训练营(第三场)- F Planting Trees

    题目链接:https://ac.nowcoder.com/acm/contest/883/F 题意:给定n×n的矩阵,求最大子矩阵使得子矩阵中最大值和最小值的差值<=M. 思路:先看数据大小,注 ...

  2. MyBatis 安装和配置

    在这里我们使用 MyBatis 开发一个简单的 Java 项目(默认你已安装JDK和MySQL及会使用Maven的基本操作),可以与上一篇通过底层操作数据进行比较 1.新建表 students,插入数 ...

  3. 什么是云数据库RDS PPAS 版

    云数据库PPAS版,是阿里云与EnterpriseDB公司合作基于PostgreSQL高度兼容Oracle语法的数据库服务,为用户提供易于操作的迁移工具,兼容范围涵盖:PL/SQL.数据类型.高级函数 ...

  4. UOJ46 玄学

    题目 一个比较自然的想法是线段树维护二进制分组. 因为我们询问的是一段连续的操作的积,所以我们可以建一棵线段树,每个节点存储当前区间各个操作的积. 这里的操作的积指的是把一系列操作做完之后区间每个位置 ...

  5. Windows 系统安装 Docker

    详细方法参见官方文档. Win10 家庭版 安装Toolbox Win10 家庭版由于功能限制,不能直接安装 Docker for Windows, 需要使用 Toolbox 的形式进行安装. 确认版 ...

  6. mysql 相关文章

    <58到家MySQL军规升级版> <数据库索引,到底是什么做的?> <MyISAM与InnoDB的索引差异究竟是啥?> <InnoDB,为何并发如此之高?&g ...

  7. 网络信息统计netstat|ss|ip

    1:netstate[弃用] netstat的作用: 需求 原命令 新命令 1:网络连接 netstat -a ss 2:路由表 netstat -r ip route 3:统计接口 netstat ...

  8. Jquery table相关--工时系统

    1.jquery 的弹出对话框,单击事件之后 if (confirm("确定要删除?")) { // //点击确定后操作 } 2.对某个table中的checkbox是否被选中的遍 ...

  9. 小P的架构生活(下)

    小L强烈建议团队使用微服务,并极力推荐了前公司用的一套分布式事务解决方案. 小P经过反复思考查证并做了大量的尝试后,辨证地对微服务架构做了如下分析: 为什么要用微服务,微服务带来了哪些好处? 1.减少 ...

  10. TP-Link 路由器 如何在现有的环境中改善无线信号传输质量

    http://service.tp-link.com.cn/detail_article_346.html