[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.pswp.cn/news/255530.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/255530.shtml
英文地址,請注明出處:http://en.pswp.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…