[BZOJ3551]ONTAK2010-Peaks加强版

题面

在Bytemountains有N座山峰,每座山峰有他的高度h_i。有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只经过困难值小于等于x的路径所能到达的山峰中第k高的山峰,如果无解输出-1。

Input

第一行三个数N,M,Q。

第二行N个数,第i个数为h_i

接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径。

接下来Q行,每行三个数v x k,表示一组询问。v=v xor lastans,x=x xor lastans,k=k xor lastans。如果lastans=-1则不变。

Output

对于每组询问,输出一个整数表示答案。

Sample Input

10 11 4
1 2 3 4 5 6 7 8 9 10
1 4 4
2 5 3
9 8 2
7 8 10
7 1 4
6 7 1
6 4 8
2 1 5
10 8 10
3 4 7
3 4 6
1 5 2
1 5 6
1 5 8
8 9 2

Sample Output

6
1
-1
8

Hint

【数据范围】N<=10^5, M,Q<=5*10 ^ 5,h_i,c,x<=10^9。

思路

在Kruscal重构树上的边点 \(x\) 的子树代表最大边权不超过 \(num[x]\) 的点组成的连通块。

那么很显然,从“v开始,困难值小于等于x"意思就是在v的所有祖先中,点权小于等于x,深度最浅的点的子树组成的连通块。

那么求第k大就相当于是在给定子树内求第k大。子树第k大可以用dfs序把树形结构转换成线性结构。那么就相当于是一个区间k大的问题了。主席树经典例题。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
#define maxn (int)(1e5+100)
#define maxm (int)(5*1e5+100)
#define maxq (maxn*2)
struct gg{int u,v,w;
}side1[maxm];
int
n,m,q,ncnt,h[maxn],fa[maxq],dep[maxq],f[maxq][21],size[maxq],seq[maxq],poi,num[maxq];
/*--------------------------------*/
int sorted[maxq],ls[maxq*20],rs[maxq*20],len,idx,sum[maxq*20],rt[maxq],cnt;
/*--------------------------------*/
vector<int>side2[maxq];
inline void read(int &x) {x = 0; char c = getchar();while (c < '0' || c > '9') c = getchar();while ('0' <= c && c <= '9') x = (x << 1) + (x << 3) + c - '0', c = getchar();
}
bool cop(gg x,gg y){return x.w<y.w;}
int getid(int x){return lower_bound(h+1,h+1+len,x)-h;
}
int update(int last,int l,int r,int num){int now=++idx;int mid=(l+r)>>1;sum[now]=sum[last]+1;ls[now]=ls[last];rs[now]=rs[last];if(l==r)return now;if(num<=mid){ls[now]=update(ls[last],l,mid,num);}else{rs[now]=update(rs[last],mid+1,r,num);}return now;
}
int lastans=0;
int get(int x){if(fa[x]==x)return x;fa[x]=get(fa[x]);return fa[x];
}
void uni(int u,int v,int w){int f_u=get(u),f_v=get(v);num[++ncnt]=w;side2[ncnt].push_back(f_u),side2[ncnt].push_back(f_v);side2[f_u].push_back(ncnt);side2[f_v].push_back(ncnt);size[ncnt]=size[f_u]+size[f_v];fa[f_u]=fa[f_v]=fa[ncnt]=ncnt;return;
}
void dfs1(int u,int g){if((int)(side2[u].size())==1){seq[u]=++poi;rt[cnt+1]=update(rt[cnt],1,len,getid(sorted[u]));cnt++;}dep[u]=dep[g]+1;f[u][0]=g;for(int i=1;i<=20;i++)f[u][i]=f[f[u][i-1]][i-1];for(int i=0;i<(int)(side2[u].size());i++){int v=side2[u][i];if(v==g)return;dfs1(v,u);}return;
}
int build(int l,int r){int now=++idx;int mid=(l+r)>>1;if(l==r)return now;ls[now]=build(l,mid);rs[now]=build(mid+1,r);return now;
}
int dfs2(int u,int lim,int last){if(num[u]>lim)return 0;if(u==ncnt)return u;for(int i=20;i>=0;i--){if(num[f[u][i]]<=lim&&f[u][i]!=0){u=f[u][i];}}return u;
}
inline int query(int last,int now,int k,int l,int r){if(l==r)return l;int mid=(l+r)>>1;int val=sum[ls[now]]-sum[ls[last]];if(k<=val){return query(ls[last],ls[now],k,l,mid);}else{return query(rs[last],rs[now],k-val,mid+1,r);}
}
int get_kth(int l,int r,int k){if(r-l+1<k){lastans=-1;return -1;}k=(r-l+2)-k;lastans=h[query(rt[l-1],rt[r],k,1,len)];return lastans;
}
int main(){read(n),read(m),read(q);for(int i=1;i<=n;i++){read(h[i]);sorted[i]=h[i];}for(int i=1;i<=m;i++){read(side1[i].u),read(side1[i].v),read(side1[i].w);}sort(side1+1,side1+1+m,cop);for(int i=1;i<=n;i++){fa[i]=i;size[i]=1;}ncnt=n;for(int i=1;i<=m;i++){int u=side1[i].u,v=side1[i].v,w=side1[i].w;if(get(u)==get(v))continue;uni(u,v,w);}sort(h+1,h+1+n);len=unique(h+1,h+1+n)-h-1;rt[0]=build(1,len);dfs1(ncnt,0);for(int i=1;i<=q;i++){int a,b,c;read(a),read(b),read(c);if(lastans!=-1){a^=lastans;b^=lastans;c^=lastans;}if(size[get(a)]<c){lastans=-1;printf("-1\n");continue;}int top=dfs2(side2[a][0],b,a);if(!top){lastans=-1;printf("-1\n");continue;}int buttom=top,last=top;while(side2[buttom][0]!=last){last=buttom,buttom=side2[buttom][0];}printf("%d\n",get_kth(seq[buttom],seq[buttom]+size[top]-1,c));}}

转载于:https://www.cnblogs.com/GavinZheng/p/10896638.html

[BZOJ3551]ONTAK2010-Peaks加强版相关推荐

  1. bzoj3551: [ONTAK2010]Peaks加强版

    很明显只有最小生成树里面的点有用 我会一个离线的做法,把询问边长排序,逐步合并树,启发式合并splay 在线怎么做呢? 考虑合并出最小生成树的过程,两点合并是并不是一边连向一边而是建出新点,并将新点连 ...

  2. bzoj3551 [ONTAK2010]Peaks加强版 kruskal重构树

    最大边最小,就是最小生成树,可以考虑用主席树维护father数组,但不能遍历子集查找 然后就只能牺牲一部分空间时间来多存一些东西 多存的就是边值大小顺序,本来以为是用主席树排边值,结果由于此题有2种数 ...

  3. #3551. [ONTAK2010]Peaks加强版(kruskal 重构树 + 主席树)

    #3551. [ONTAK2010]Peaks加强版 我们要求从一个点出发经过困难值小于等于xxx的路径所能到达的山峰中第kkk高的是什么. 考虑按照边权升序,建议kruskalkruskalkrus ...

  4. ONTAK2010 Peaks加强版(离线在线)

    题面 弱化版:luogu 强制在线版:bzoj 题解 本题有两种解法 离线算法:线段树合并 先看一道简单题[USACO18JAN]MooTube 本题就是在此基础上求第\(k\)高的点 首先把询问和路 ...

  5. [ONTAK2010] Peaks加强版 (kruskal重构树+主席树+倍增)

    Peaks description solution code description 在Bytemountains有N座山峰,每座山峰有他的高度h_i 有些山峰之间有双向道路相连,共M条路径,每条路 ...

  6. BZOJ.3551. [ONTAK2010]Peaks加强版

    传送门 类似可以离线处理的题目Peaks KruskalKruskalKruskal重构树 强制在线,主要就考一个[重构树]以及[树链剖分]+[静态区间第K大],离散化建立一颗权值线段树即可 重构树的 ...

  7. 【BZOJ3551】Peaks加强版,主席树+kruskal重构+dfs序+倍增思想

    传送门 写在前面:一道调了不止一上午的题目 思路:我们先来看一下神奇的kruskal重构树 图中红色的是原图的边权,黑色的是原图上的点 这样生成的树有一些十分优美的性质: 1.二叉树(好吧这题意义不大 ...

  8. P7834 [ONTAK2010] Peaks 加强版

    传送门 题目大意 感觉题目描述已经足够清楚了. Solution 这道题需要的东西有点多,我们不妨先来分解一下题目的需求. 经过权值 ≤ x \le x ≤x 的边所能到达的点. 马上想到最小生成树, ...

  9. [BZOJ3545][ONTAK2010]Peaks

    [BZOJ3545][ONTAK2010]Peaks 试题描述 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越 ...

  10. Peaks加强版 黑暗爆炸 - 3551 Kruskal重构树 + 主席树

    传送门 文章目录 题意: 思路: 题意: 给你一张图,有nnn个山峰,每个山峰高度为hih_ihi​,有mmm条边,每条边有个难度值wiw_iwi​,现在有qqq个询问,每次询问给定一个山峰vvv,问 ...

最新文章

  1. android启动流程之lk,Android系统之LK启动流程分析(一)
  2. 深入理解分布式技术 - 消息幂等性如何保障不重复消费
  3. 在对人的管理上,项目经理应该做些什么?
  4. ORA-06502:PL/SQL :numberic or value error: character string buffer too small
  5. jQuery 操作 CSS
  6. 微软把UWP定位成业务线应用程序开发平台
  7. Linux Jump Label(x86)
  8. EasyUI:datagrid分页显示+嵌入select下拉选项框
  9. 【基础教程】基于matlab生成Word+PPT报告【含Matlab源码 971期】
  10. word排版教程-----------技巧
  11. vbscript mysql_vbscript 数据库操作
  12. 填充因子设置的一般性准则和指导
  13. Android audio 二 AudioRecord 分析上
  14. Linux技术--mysql数据库增-删-改-查
  15. 重装系统(win10企业版)
  16. 小程序图片长按识别功能的实现
  17. CSDN-MarkDown编辑器的姿势大全
  18. Oracle11gR2(二)-图形安装
  19. Python datetime日期 加一个月
  20. PPTV去广告(XP测试通过)

热门文章

  1. 使用Python 录音、调整音量、播放
  2. EA以7.5亿美元收购植物大战僵尸开发商PopCap
  3. shutdown定时关机或者注销
  4. Cesium路径回放
  5. java 汉字转拼音工具_【转载】Java汉字转全拼工具
  6. 好消息!2021大数据独角兽企业榜单出炉!智领云再上榜!
  7. ADS2020安装陷阱你学废了吗,小白狂喜教程
  8. 京东api接口php sdk,GitHub - ifwrong/jos-php-sdk: 京东php版本开放平台SDK
  9. 我的世界服务器物品管道,我的世界EIO教程末影接口mod物品导管合成方法与使用...
  10. qgc开发文档_QGC地面站二次开发教程二