[BZOJ3545][ONTAK2010]Peaks

[BZOJ3545][ONTAK2010]Peaks

试题描述

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

输入

第一行三个数N,M,Q。
第二行N个数,第i个数为h_i
接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径。
接下来Q行,每行三个数v x k,表示一组询问。

输出

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

输入示例

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

输出示例

6
1
-1
8

数据规模及约定

N<=10^5, M,Q<=5*10^5,h_i,c,x<=10^9。

题解

考虑离线做法,我们把边和询问按权值排一遍序,然后依次处理每个询问。那么就是从小到大依次加入那些边,对于连通性,我们可以用并查集维护;对于第 k 大值,我们可以并查集里面套一个 treap;啊 treap 怎么合并?只好加一个 log 启发式合并了。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std;const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *Tail;
inline char Getchar() {if(Head == Tail) {int l = fread(buffer, 1, BufferSize, stdin);Tail = (Head = buffer) + l;}return *Head++;
}
int read() {int x = 0, f = 1; char c = Getchar();while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }return x * f;
}#define maxn 100010
#define maxm 500010
struct Node {int v, r, siz;Node() {}Node(int _, int __): v(_), r(__) {}
} ns[maxn];
int ToT, fa[maxn], ch[maxn][2], rec[maxn], rcnt;
int getnode() {if(rcnt) {int o = rec[rcnt--];fa[o] = ch[o][0] = ch[o][1] = 0;return o;}return ++ToT;
}
void maintain(int o) {ns[o].siz = 1;for(int i = 0; i < 2; i++) if(ch[o][i])ns[o].siz += ns[ch[o][i]].siz;return ;
}
void rotate(int u) {int y = fa[u], z = fa[y], l = 0, r = 1;if(z) ch[z][ch[z][1]==y] = u;if(ch[y][1] == u) swap(l, r);fa[u] = z; fa[y] = u; fa[ch[u][r]] = y;ch[y][l] = ch[u][r]; ch[u][r] = y;maintain(y); maintain(u);return ;
}
void insert(int& o, int v) {if(!o) {ns[o = getnode()] = Node(v, rand());return maintain(o);}bool d = v > ns[o].v;insert(ch[o][d], v); fa[ch[o][d]] = o;if(ns[ch[o][d]].r > ns[o].r) {int t = ch[o][d];rotate(t); o = t;}return maintain(o);
}
int val[maxn], cntv;
void recycle(int& o) {if(!o) return ;recycle(ch[o][0]); recycle(ch[o][1]);rec[++rcnt] = o; val[++cntv] = ns[o].v; fa[o] = 0; o = 0;return ;
}
void merge(int& u, int& v) {
//	printf("merge(%d, %d)\n", u, v);cntv = 0; recycle(v);
//	printf("vals: "); for(int i = 1; i <= cntv; i++) printf("%d%c", val[i], i < cntv ? ' ' : '\n');for(int i = 1; i <= cntv; i++) insert(u, val[i]);return ;
}
int Find(int o, int k) {if(!o) return -1;int rs = ch[o][1] ? ns[ch[o][1]].siz : 0;if(k == rs + 1) return ns[o].v;if(k < rs + 1) return Find(ch[o][1], k);return Find(ch[o][0], k - rs - 1);
}int pa[maxn], rt[maxn];
int findset(int x) { return x == pa[x] ? x : pa[x] = findset(pa[x]); }struct Edge {int a, b, c;Edge() {}Edge(int _1, int _2, int _3): a(_1), b(_2), c(_3) {}bool operator < (const Edge& t) const { return c < t.c; }
} es[maxm];
struct Que {int u, x, k, id;Que() {}Que(int _1, int _2, int _3, int _4): u(_1), x(_2), k(_3), id(_4) {}bool operator < (const Que& t) const { return x < t.x; }
} qs[maxm];
int ans[maxm];int main() {int n = read(), m = read(), q = read();for(int i = 1; i <= n; i++) {int v = read();pa[i] = i; insert(rt[i], v);}for(int i = 1; i <= m; i++) {int a = read(), b = read(), c = read();es[i] = Edge(a, b, c);}sort(es + 1, es + m + 1);for(int i = 1; i <= q; i++) {int u = read(), x = read(), k = read();qs[i] = Que(u, x, k, i);}sort(qs + 1, qs + q + 1);//	for(int i = 1; i <= m; i++) printf("Edge: %d %d %d\n", es[i].a, es[i].b, es[i].c);
//	for(int i = 1; i <= q; i++) printf("Que: %d %d %d\n", qs[i].u, qs[i].x, qs[i].k);for(int i = 1, e = 1; i <= q; i++) {while(e <= m && es[e].c <= qs[i].x) {int u = findset(es[e].a), v = findset(es[e].b);
//			printf("%d: %d(%d) %d(%d) %d\n", e, u, es[e].a, v, es[e].b, findset(8));if(u != v) {if(ns[rt[u]].siz < ns[rt[v]].siz) swap(u, v);merge(rt[u], rt[v]);pa[v] = u;}e++;}ans[qs[i].id] = Find(rt[findset(qs[i].u)], qs[i].k);}for(int i = 1; i <= q; i++) printf("%d\n", ans[i]);return 0;
}

在线做法,详见这里。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std;const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *Tail;
inline char Getchar() {if(Head == Tail) {int l = fread(buffer, 1, BufferSize, stdin);Tail = (Head = buffer) + l;}return *Head++;
}
int read() {int x = 0, f = 1; char c = Getchar();while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }return x * f;
}#define maxn 200010
#define maxm 500010
#define maxlog 18
#define maxnode 6666666
int n;int ToT, sumv[maxnode], lc[maxnode], rc[maxnode], rt[maxn];
void update(int& y, int x, int l, int r, int p) {sumv[y = ++ToT] = sumv[x] + 1;if(l == r) return ;int mid = l + r >> 1; lc[y] = lc[x]; rc[y] = rc[x];if(p <= mid) update(lc[y], lc[x], l, mid, p);else update(rc[y], rc[x], mid + 1, r, p);return ;
}struct Edge {int a, b, c;Edge() {}Edge(int _1, int _2, int _3): a(_1), b(_2), c(_3) {}bool operator < (const Edge& t) const { return c < t.c; }
} es[maxm];
int p_ToT, fa[maxlog][maxn], ch[maxn][2], p_val[maxn], e_val[maxn], dl[maxn], dr[maxn], clo, pid[maxn];
void build(int u) {if(!u) return ;
//	printf("%d u: %d %d %d\n", e_val[u], u, ch[u][0], ch[u][1]);dl[u] = ++clo; pid[clo] = u;for(int i = 1; i < maxlog; i++) fa[i][u] = fa[i-1][fa[i-1][u]];for(int i = 0; i < 2; i++) build(ch[u][i]);dr[u] = clo;return ;
}int pa[maxn], id[maxn];
int findset(int x) { return x == pa[x] ? x : pa[x] = findset(pa[x]); }int num[maxn];
int query(int u, int mx, int k, int id) {for(int i = maxlog - 1; i >= 0; i--) if(fa[i][u] && e_val[fa[i][u]] <= mx) u = fa[i][u];
//	printf("%d %d\n", u, e_val[u]);int lrt = rt[dl[u]-1], rrt = rt[dr[u]];int l = 1, r = n;while(l < r) {int mid = l + r >> 1;
//		printf("[%d, %d]: %d %d\n", mid + 1, r, sumv[rc[rrt]] - sumv[rc[lrt]], k);if((rrt && rc[rrt] ? sumv[rc[rrt]] : 0) - (lrt && rc[lrt] ? sumv[rc[lrt]] : 0) < k) {k -= sumv[rc[rrt]] - sumv[rc[lrt]]; r = mid;if(lrt) lrt = lc[lrt]; if(rrt) rrt = lc[rrt];}else {l = mid + 1;if(lrt) lrt = rc[lrt]; if(rrt) rrt = rc[rrt];}}int ans = sumv[rrt] - sumv[lrt] >= k ? l : -1;return ans < 0 ? ans : num[ans];
}int main() {freopen("data.in", "r", stdin);freopen("data.out", "w", stdout);n = read(); int m = read(), q = read();for(int i = 1; i <= n; i++) num[i] = p_val[i] = read(), pa[i] = id[i] = i;sort(num + 1, num + n + 1);for(int i = 1; i <= n; i++) p_val[i] = lower_bound(num + 1, num + n + 1, p_val[i]) - num;for(int i = 1; i <= m; i++) {int a = read(), b = read(), c = read();es[i] = Edge(a, b, c);}sort(es + 1, es + m + 1);p_ToT = n;for(int i = 1; i <= m; i++) {int u = findset(es[i].a), v = findset(es[i].b);if(u != v) {ch[++p_ToT][0] = id[u];ch[p_ToT][1] = id[v];fa[0][id[v]] = fa[0][id[u]] = p_ToT;e_val[p_ToT] = es[i].c;pa[v] = u; id[u] = p_ToT;}}build(id[findset(1)]);for(int i = 1; i <= clo; i++)if(p_val[pid[i]]) update(rt[i], rt[i-1], 1, n, p_val[pid[i]]);else rt[i] = rt[i-1];int lst = 0;for(int i = 1; i <= q; i++) {int v = read() ^ lst, x = read() ^ lst, k = read() ^ lst;lst = query(v, x, k, i);printf("%d\n", lst); if(lst < 0) lst = 0;lst = 0;}return 0;
}

 

转载于:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/6351552.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/255530.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

杭电1027Ignatius and the Princess II模拟

地址&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid1027 题目&#xff1a; Problem DescriptionNow our hero finds the door to the BEelzebub feng5166. He opens the door and finds feng5166 is about to kill our pretty Princess. But now the BEelzebub has t…

angular 使用rxjs 监听同级兄弟组件数据变化

angular 的官网给出了父子组件之间数据交互的方法&#xff0c;如ViewChild、EventEmitter 但是如果要在同级组件之间进行数据同步&#xff0c;似乎并没有给出太多的信息。 有时候我们想&#xff0c;在一个组件中修改数据之后&#xff0c;马上反映到另外一个组件中&#xff0c; …

OpenCV里IplImage的widthStep参数 和width参数

一直以为IplImage结构体中的widthStep元素大小等于width*nChannels&#xff0c;大错特错&#xff01;&#xff08;为了快速访问&#xff0c;要内存对齐啊&#xff09;查看OpenCV2.1的源码&#xff0c;在src/cxcore/cxarray.cpp文件中&#xff0c;找到cvInitImageHeader函数&…

【数字信号处理】——Python频谱绘制

# -*- coding: utf-8 -*- from matplotlib import pyplotpyplot.rcParams[font.sans-serif] [SimHei] pyplot.rcParams[axes.unicode_minus] Falseimport numpy as np import matplotlib.pyplot as pl import matplotlib import math import randomN 500 # 绘制点总数 fs 5…

Android开发:《Gradle Recipes for Android》阅读笔记1.3

想命令行执行gradle的构建&#xff0c;可以通过提供的gradle wrapper或者安装gradle。 构建android项目不需要安装gradle&#xff0c;因为android studio已经包含gradle。"gradle wrapper"指的是根目录下的gradlew和gradlew.bat脚本&#xff08;结尾的w是wrapper的意…

pic

转载于:https://www.cnblogs.com/edisonxiang/p/5392651.html

leetcode 643 Maximum Average Subarray I

题目详情 Given an array consisting of n integers, find the contiguous subarray of given length k that has the maximum average value. And you need to output the maximum average value. 输入一个数组nums和一个整数k。要求找出输入数组中长度为k的子数组&#xff0c…

OpenCV之cvSmooth函数平滑滤波

1、cvSmooth函数用法 定义原型 <span style"font-size:12px;"> void cvSmooth( const CvArr* src, CvArr* dst,int smoothtypeCV_GAUSSIAN,int param1, int param2, double param3, double param4 );</span>src:输入图像. dst:输出图像. smoot…

【python数字信号处理】——DFT、DTFT(频谱图、幅度图、相位图)

目录 一、离散时间傅里叶变换DTFT 二、离散傅里叶变换DFT 三、DFT与DTFT的关系 ​ 参考&#xff1a; 《数字信号处理》——&#xff08;一&#xff09;.DTFT、DFT(python实现)_远行者223的博客-CSDN博客python绘制频谱图DTFT&#xff0c;DFTpython绘制频谱图&#xff1a;…

ERROR:Tried to register widget id ==basemapGalleryDiv but that id is already registered解决办法

在ArcGIS Server开发中&#xff0c;遇到DIV已经被注册的情况&#xff0c;不能对原DIV内容进行更新。这里需要调用Dojo的destroyRecursive&#xff08;&#xff09;方法&#xff0c;逐个销毁该Widget下的子元素及其后代元素。然后就可以在原DIV上注册新的小部件。 示例代码&…

通过Spring Data Neo4J操作您的图形数据库

在前面的一篇文章《图形数据库Neo4J简介》中&#xff0c;我们已经对其内部所使用的各种机制进行了简单地介绍。而在我们尝试对Neo4J进行大版本升级时&#xff0c;我发现网络上并没有任何成型的样例代码以及简介&#xff0c;而其自身的文档也对如何使用Spring Data Neo4J介绍得语…

图像金字塔

图像金字塔被广泛用于各种视觉应用中。图像金字塔是一个图像集合&#xff0c;集合中所有的图像都源于同一个原始图像&#xff0c;而且是通过对原始图像连续降采样活得&#xff0c;直到达到某个中止条件才停止降采样。&#xff08;当然&#xff0c;降为一个像素肯定是中止条件。…

python使用git进行版本控制-分支管理

1、远程克隆 最好的方式是先创建远程库&#xff0c;然后&#xff0c;从远程库克隆&#xff1a; 首先在github上创建一个新的仓库&#xff0c;名字叫gitskills 我们勾选Initialize this repository with a README&#xff0c;这样GitHub会自动为我们创建一个README.md文件。 下一…

【python数字信号处理】——Z变换

目录 一、公式 二、代码 三、结果 一、公式 频域变量&#xff1a;z 时域变量&#xff1a;n 常见序列的Z变换&#xff1a;信号与系统复习归纳&#xff08;十一&#xff09;&#xff1a;Z变换例题_百把人的博客-CSDN博客_z变换例题基于东南大学陈从颜译《信号、系统和变换》和…

九宫格拼图 支持44 55等

代码下载转载于:https://www.cnblogs.com/ygcool/p/5395343.html

144. Binary Tree Preorder Traversal

Given a binary tree, return the preorder traversal of its nodes values. For example:Given binary tree {1,#,2,3}, 1\2/3return [1,2,3]. 该题是对树做前序遍历 下面分别是递归&#xff0c;非递归&#xff0c;分治三种思路的解题结果 #递归写法 class Solution(object):d…

一体化点焊机将要取代分体式焊钳在汽车制造生产线上的使用

目前大多数汽车制造厂及相关配套钣金件厂家选用的是悬挂式点焊机及分体式焊钳&#xff0c;从焊接变压器的功率参数看&#xff0c;约70 % 为160KVA 的&#xff0c;约30 % 为200 kVA 的。原因主要有两方面&#xff0c;一是新材料如镀锌钢板、高强度钢板、铝合金板的应用&#xff…

【python数字信号处理】——线性卷积

目录 一、公式概念 二、代码 1、numpy库 2、自定义打印出每一步结果 三、结果 一、公式概念 线性卷积_百度百科线性卷积(linear convolution) 在时域描述线性系统输入和输出之间关系的一种运算。这种运算在线性系统分析和信号处理中应用很多&#xff0c;通常简称卷积。中文…

activiti web流程设计器 整合视频 教程 SSM和独立部署的方式

本视频为activiti工作流的web流程设计器整合视频教程整合Acitiviti在线流程设计器(Activiti-Modeler 5.21.0 官方流程设计器&#xff09;本视频共讲了两种整合方式1. 流程设计器和其它工作流项目分开部署的方式2. 流程设计器和SSM框架项目整合在一起的方式视频大小 1.13 GB ~【…

移动端判断横屏竖屏

1. CSS判断横屏竖屏 写在同一个CSS中 media screen and (orientation: portrait) {   /*竖屏 css*/} media screen and (orientation: landscape) and (min-width:450px){   /*横屏 css*/}分开写在2个CSS 竖屏<link rel"stylesheet" media"all and (orie…