很明显只有最小生成树里面的点有用

我会一个离线的做法,把询问边长排序,逐步合并树,启发式合并splay

在线怎么做呢?

考虑合并出最小生成树的过程,两点合并是并不是一边连向一边而是建出新点,并将新点连向两边边权为这两点的边权。重构出新树后,所有原点都是叶子节点,并且边权深到浅单增,可以用倍增找到断开的位置,问题变成求子树中第k大的值,上一个主席树就好了

码力堪忧

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const int _=1e2;
const int maxn=1e5+_;
const int maxp=2*maxn;
const int maxm=5e5+_;
const int maxQ=5e5+_;
int n,m,Q,w[maxn]; int lslen,ls[maxn];
inline int read()
{int x=0,f=1;char ch=getchar();while(!isdigit(ch))ch=getchar();while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}return x*f;
}
inline void write(int d)
{if(d>=10)write(d/10);putchar(d%10+'0');
}namespace CHAIR
{struct trnode{int lc,rc,c;}tr[12*maxp];int trlen,rt[maxp];int maketree(int now,int l,int r,int p){if(now==0)now=++trlen;tr[now].c++;if(l!=r){int mid=(l+r)/2;if(p<=mid)tr[now].lc=maketree(tr[now].lc,l,mid,p);else tr[now].rc=maketree(tr[now].rc,mid+1,r,p);}return now;}int merge(int x,int y){if(x==0||y==0)return x+y;tr[x].c+=tr[y].c;tr[x].lc=merge(tr[x].lc,tr[y].lc);tr[x].rc=merge(tr[x].rc,tr[y].rc);return x;}int findkth(int x,int y,int l,int r,int k){if(tr[y].c-tr[x].c<k)return -1;if(l==r)return l;int mid=(l+r)/2;int c=tr[tr[y].rc].c-tr[tr[x].rc].c;if(c>=k)return findkth(tr[x].rc,tr[y].rc,mid+1,r,k);else return findkth(tr[x].lc,tr[y].lc,l,mid,k-c);}
}struct node
{int x,y,d,next;
}a[maxp];int len,last[maxp];
void ins(int x,int y,int d)
{len++;a[len].x=x;a[len].y=y;a[len].d=d;a[len].next=last[x];last[x]=len;
//    printf("%d %d %d\n",x,y,d);
}
int z,L[maxp],R[maxp],de[maxp];
int dep[maxp],f[30][maxp];
void dfs(int x)
{for(int i=1;(1<<i)<=dep[x];i++)f[i][x]=f[i-1][f[i-1][x]];L[x]=++z;if(last[x]==0){CHAIR::rt[z]=CHAIR::maketree(CHAIR::rt[z],1,lslen,w[x]);CHAIR::rt[z]=CHAIR::merge(CHAIR::rt[z],CHAIR::rt[z-1]);}else CHAIR::rt[z]=CHAIR::rt[z-1];for(int k=last[x];k;k=a[k].next){int y=a[k].y; de[y]=a[k].d;f[0][y]=x;dep[y]=dep[x]+1;dfs(y);}R[x]=z;
}int fa[maxp];
int findfa(int x)
{if(fa[x]==x)return x;fa[x]=findfa(fa[x]);return fa[x];
}
struct edge{int x,y,d;}e[maxm];
bool cmp(edge e1,edge e2){return e1.d<e2.d;}
int main()
{freopen("a.in","r",stdin);freopen("a.out","w",stdout);n=read(),m=read(),Q=read();for(int i=1;i<=n;i++)w[i]=read(),ls[++lslen]=w[i];sort(ls+1,ls+lslen+1);lslen=unique(ls+1,ls+lslen+1)-ls-1;for(int i=1;i<=n;i++)w[i]=lower_bound(ls+1,ls+lslen+1,w[i])-ls;for(int i=1;i<=m;i++)e[i].x=read(),e[i].y=read(),e[i].d=read();sort(e+1,e+m+1,cmp);int fx,fy;for(int i=1;i<=2*n;i++)fa[i]=i;for(int i=1;i<=m;i++){fx=findfa(e[i].x),fy=findfa(e[i].y);if(fx!=fy){n++; fa[fx]=n,fa[fy]=n;ins(n,fx,e[i].d);ins(n,fy,e[i].d);}}dfs(n);int x,k,d,lastans=0;while(Q--){x=read(),d=read(),k=read();x^=lastans,k^=lastans,d^=lastans;if(de[x]>d){if(k==1)lastans=w[x],printf("%d\n",w[x]);else puts("-1"),lastans=0;continue;}for(int i=25;i>=0;i--)if((1<<i)<dep[x]&&de[f[i][x]]<=d)x=f[i][x];x=f[0][x];lastans=CHAIR::findkth(CHAIR::rt[L[x]-1],CHAIR::rt[R[x]],1,lslen,k);if(lastans!=-1){lastans=ls[lastans];write(lastans),putchar('\n');}else puts("-1"),lastans=0;}return 0;
}

转载于:https://www.cnblogs.com/AKCqhzdy/p/10730777.html

bzoj3551: [ONTAK2010]Peaks加强版相关推荐

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

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

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

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

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

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

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

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

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

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

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

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

  7. P7834 [ONTAK2010] Peaks 加强版

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

  8. [BZOJ3545][ONTAK2010]Peaks

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

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

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

最新文章

  1. css3关键帧动画以及兼容性策略
  2. gettype拿不到值_被玩家强行改位置的5个英雄,他上单无解,杀吕布灭铠爹,这都拿去辅助?...
  3. php作业90,php中文网移动端-第九期(191107作业)
  4. 友邦人寿引入阿里云PolarDB云数据库 支撑保险业务系统加速上云
  5. java windows域_域环境中的windows软件安装
  6. 让你的php命令行程序处理管道数据
  7. win 10 配置docker 阿里云 加速器
  8. echarts曲线太多卡顿怎么优化_光刻胶旋涂曲线如何获得?
  9. Python+Selenium+Firefox配置,及可以启动浏览器,不能自动输入地址
  10. 假期无聊 就来试试用Python做一个智能识别 包教会哦 多图预警:配置Pyqt5超详细解说(designer.exe和pyuic.exe)以及项目:Python实现百度智能识别,识别各种实物
  11. MySQL 线程池[2021-06-26]
  12. element-ui表格编辑
  13. python识别字母代码_【Python-Opencv】KNN英文字母识别
  14. php 怎样清除浏览器痕迹,如何清除电脑使用痕迹?上网痕迹清理的方法介绍
  15. flex trace无法使用
  16. 目标检测 YOLOv5 - ncnn模型的加密 C++实现封装库和Android调用库示例
  17. 免费顺丰快递鸟单号查询不限次数api接口申请步骤
  18. Matlab中的diag函数用法
  19. IBM内存分析工具JCA在windows环境下打开dump文件报错问题:Cannot find any thread dumps
  20. web前端优化(加快加载速度,由点滴做起)

热门文章

  1. Java方法重载与方法重写
  2. 群晖 设置 php 服务器,群晖NAS服务器iSCSI管理器配置连接及使用说明
  3. 重构智能合约(中):平行宇宙与无限扩展
  4. IPFS:Filecoin和复制证明
  5. How to Build Your Own Blockchain Part 4.2 — Ethereum Proof of Work Difficulty Explained
  6. JZOJ 5438. 【NOIP2017提高A组集训10.31】Tree
  7. Qt模型、视图解读之视图
  8. python元胞自动机模拟交通_大师兄带你复现 -gt; 难度超高的二维CA元胞自动机模型...
  9. 血栓清道夫机器人_血栓“清道夫”找到了!洋葱排最后,排在第一很多人并不知道...
  10. django的from组件