Peaks加强版 黑暗爆炸 - 3551 Kruskal重构树 + 主席树
传送门
文章目录
- 题意:
- 思路:
题意:
给你一张图,有nnn个山峰,每个山峰高度为hih_ihi,有mmm条边,每条边有个难度值wiw_iwi,现在有qqq个询问,每次询问给定一个山峰vvv,问从这个山峰开始走,经过难度不超过xxx的路径能走到的山峰中,第kkk大的山峰高度是多少。
n≤1e5,m,q≤5e5,hi,wi<=1e9n\le1e5,m,q\le5e5,h_i,w_i<=1e9n≤1e5,m,q≤5e5,hi,wi<=1e9
思路:
KruskalKruskalKruskal重构树维护连通性经典题啦,把边从小到大排序,让后建重构树,这样每两个点之间的最大路径是他们的lcalcalca的点权,那么我们从vvv这个点往上跳,一直跳到深度最小的且valf≤xval_f\le xvalf≤x的点,让后这颗子树中所有叶子节点就是能到的山峰,找第kkk大的问题当然是留给主席树解决啦,按照dfsdfsdfs序建主席树,查询第kkk大就好了。
//#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
//#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#include<ctime>
#include<cstdlib>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define pb push_back
#define mk make_pair
#define Mid (tr[u].l+tr[u].r>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define db puts("---")
using namespace std;//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); }
//void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); }
//void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;const int N=200010,mod=1e9+7,INF=0x3f3f3f3f;
const double eps=1e-6;int n,m,q;
int a[N],p[N],fa[N][22],in[N],ed[N],se[N],tot;
int root[N],idx,h[N];
vector<int>v[N],li;
struct Edge
{int a,b,w;bool operator < (const Edge &W) const{return w<W.w;}
}edge[N*3];
struct Node
{int l,r;int cnt;
}tr[N*40];int find(int x)
{return x==p[x]? x:p[x]=find(p[x]);
}int get(int x)
{return lower_bound(li.begin(),li.end(),x)-li.begin();
}void insert(int p,int &q,int l,int r,int pos)
{q=++idx; tr[q]=tr[p];tr[q].cnt++;if(l==r) return;int mid=(l+r)>>1;if(pos<=mid) insert(tr[p].l,tr[q].l,l,mid,pos);else insert(tr[p].r,tr[q].r,mid+1,r,pos);
}int query(int p,int q,int l,int r,int k)
{if(l==r) return li[l];int mid=(l+r)>>1,cnt=tr[tr[q].l].cnt-tr[tr[p].l].cnt;if(k<=cnt) return query(tr[p].l,tr[q].l,l,mid,k);else return query(tr[p].r,tr[q].r,mid+1,r,k-cnt);
}void dfs(int u,int f)
{se[u]=1;in[u]=++tot; fa[u][0]=f;for(int i=1;i<=19;i++) fa[u][i]=fa[fa[u][i-1]][i-1];if(u<=n) insert(root[tot-1],root[tot],0,li.size()-1,get(a[u]));else root[tot]=root[tot-1];for(auto x:v[u]) if(x!=f) dfs(x,u),se[u]+=se[x];ed[u]=tot;
}int main()
{// ios::sync_with_stdio(false);
// cin.tie(0);scanf("%d%d%d",&n,&m,&q);for(int i=1;i<=n;i++) scanf("%d",&a[i]),li.pb(a[i]);sort(li.begin(),li.end()); li.erase(unique(li.begin(),li.end()),li.end());for(int i=1;i<=n*2;i++) p[i]=i;for(int i=1;i<=m;i++){int a,b,w; scanf("%d%d%d",&a,&b,&w);edge[i]={a,b,w};}sort(edge+1,edge+1+m);for(int i=1,tot=n;i<=m;i++){int aa=edge[i].a,b=edge[i].b,w=edge[i].w;int pa=find(aa),pb=find(b);if(pa==pb) continue;tot++; p[pa]=tot; p[pb]=tot;v[tot].pb(pa); v[tot].pb(pb);a[tot]=w;if(tot==n*2-1) break;//cout<<pa<<' '<<pb<<' '<<tot<<' '<<w<<endl;}a[0]=INF;for(int i=1;i<=n*2-1;i++) if(i==find(i)) dfs(i,0);int ans=0;while(q--){int v,x,k; scanf("%d%d%d",&v,&x,&k);v^=ans; x^=ans; k^=ans; for(int i=19;i>=0;i--) if(a[fa[v][i]]<=x) v=fa[v][i];int sum=tr[root[ed[v]]].cnt-tr[root[in[v]-1]].cnt;if(k>sum) ans=-1;else ans=query(root[in[v]-1],root[ed[v]],0,li.size()-1,sum-k+1);printf("%d\n",ans);ans=ans==-1? 0:ans;}return 0;
}
/**/
Peaks加强版 黑暗爆炸 - 3551 Kruskal重构树 + 主席树相关推荐
- [ONTAK2010] Peaks加强版 (kruskal重构树+主席树+倍增)
Peaks description solution code description 在Bytemountains有N座山峰,每座山峰有他的高度h_i 有些山峰之间有双向道路相连,共M条路径,每条路 ...
- LOJ.2865.[IOI2018]狼人(Kruskal重构树 主席树)
LOJ 洛谷 这题不就是Peaks(加强版)或者归程么..这算是\(IOI2018\)撞上\(NOI2018\)的题了? \(Kruskal\)重构树(具体是所有点按从小到大/从大到小的顺序,依次加入 ...
- #3551. [ONTAK2010]Peaks加强版(kruskal 重构树 + 主席树)
#3551. [ONTAK2010]Peaks加强版 我们要求从一个点出发经过困难值小于等于xxx的路径所能到达的山峰中第kkk高的是什么. 考虑按照边权升序,建议kruskalkruskalkrus ...
- P4197-Peaks【Kruskal重构树,主席树】
正题 题目链接:https://www.luogu.com.cn/problem/P4197 题目大意 nnn个点的一张无向图,每个点有一个hih_ihi,边有权值. qqq次询问从vvv出发不走权 ...
- P4899 [IOI2018] werewolf 狼人(kruskal 重构树 + 主席树)
P4899 [IOI2018] werewolf 狼人 给定一个有nnn个点mmm条边的无向图,有QQQ个询问 每次输入S,E,L,RS, E, L, RS,E,L,R,表示你在SSS点出发,要到EE ...
- P4899-[IOI2018]werewolf 狼人【Kruskal重构树,主席树】
正题 题目链接:https://www.luogu.com.cn/problem/P4899 题目大意 nnn个点的一张无向图,每次询问(s,t,l,r)(s,t,l,r)(s,t,l,r)表示询问能 ...
- 牛客 - 牛半仙的妹子图(并查集+bitset/克鲁斯卡尔重构树+主席树)
题目链接:点击查看 题目大意:给出一个由 n 个点和 m 条边组成的连通图,每个点都有一种颜色,每条边都有一个权值,现在规定一个起点 st,再给出 q 次询问,每次询问给出区间 [ l , r ] , ...
- Pandaria(Kruskal重构树+线段树合并)
题意 是 有n个花园 一个花园内所有的花的颜色都是一样的 有很多种不同的颜色 花园到花园之间有路,走不同的路有不同的代价 如果选一个点作为起点 只走小于等于w的路 可以经过的这些花园里 那 ...
- Network 黑暗爆炸 - 3732 倍增lca || Kruskal重构树
传送门 文章目录 题意: 思路: 题意: 思路: 两点间最长边最小值一定是最小生成树上两点间的最大值,这个比较容易证,就不多说了. 知道这个结论后, 我们直接跑一个KruskalKruskalKrus ...
最新文章
- luogu 1471
- Linux中shell的分类以及查看当前的shell
- 安装翻译_【现象】面对日益增多的外国人 日本安装远程翻译设施
- [十二省联考 2019] 异或粽子(可持久化字典树 + 二叉堆)
- tf.group()用于组合多个操作
- CDOJ--1850
- python3 def download_python3下载抖音视频
- Codeforces Round #110 (Div. 2)
- 《Java从入门到放弃》文章目录
- Star Way To Heaven题解(防题目重复)
- xp系统本地连接服务器,xp系统本地连接受限制或无连接怎么办丨xp本地连接断开无法上网解决办法...
- 行列式 (背诵内容)
- 在Nuxt项目中使用iconfont阿里巴巴图标unicode
- 国内Linux笔记天花板,不接受反驳!
- 大数定律是什么?为何人们更愿意相信从大数据中得到的统计结果,而不是从小数据中得到的经验呢?
- 图像处理——如何处理不同格式和深度的图像确保清晰度满足要求
- PHP接入图片文字识别AIP
- 好听的歌曲单片机c语言程序,单片机C语言程序举例(三)
- 体系化、常态化、实战化的攻防演练的现状
- 广告业务系统 之 敏捷交付 —— “基于 Docker 容器同机部署”
热门文章
- 电子商务应用课程知识整理 第二章-电子商务相关知识与技术
- 电脑怎么测试硬盘的读写速度_两块硬盘合二为一,电脑读写翻倍?这样的“好事”你必须得了解...
- 快手春节活动奖励未到账,被羊毛党投诉上了全国12315平台
- linux at java,Linux-Tutorial/Java-bin.md at master · linsanityHuang/Linux-Tutorial · GitHub
- jmeter xml 请求_Jmeter学习笔记(十六)——HTTP请求之content-type
- mybatis-plus 会自动增加 order by_python自动撸支付宝基金答题红包
- 计算机标准符合,计算机专利申请要符合哪些标准
- linux phpunit 安装,PHPUnit安装教程
- 北航卓越计划 计算机科学,解读:北京航空航天大学2017卓越计划自主招生条件...
- 算法设计与分析——动态规划——最长公共子序列