Luogu 4197 Peaks
BZOJ 3545 带权限。
考虑离线,把所有边按照从小到大的顺序排序,把所有询问也按照从小到大的顺序排序,然后维护一个并查集和一个权值线段树,每处理一个询问就把比这个询问的$x$更小的边连上,具体来说就是合并两个并查集以及两棵线段树,查询的时候在线段树上走一走就好了。
要注意查询的第$k$大不是第$k$小,所以顺便再维护一个$siz$,如果$siz < k$那答案即为$-1$。
时间复杂度$O((m + q)logn)$。
Code:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int N = 1e5 + ;
const int M = 5e5 + ;
const int inf = << ; int n, m, qn, a[N], mn = , mp[N], ufs[N], siz[N]; struct Innum {
int val, id; friend bool operator < (const Innum &x, const Innum &y) {
if(x.val == y.val) return x.id < y.id;
else return x.val < y.val;
} } in[N]; struct Pathway {
int u, v, val; friend bool operator < (const Pathway &x, const Pathway &y) {
return x.val < y.val;
} } path[M]; struct Querys {
int pos, val, k, id, res; friend bool operator < (const Querys &x, const Querys &y) {
return x.val < y.val;
} } q[M]; inline void read(int &X) {
X = ; char ch = ; int op = ;
for(; ch > '' || ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} inline void chkMax(int &x, int y) {
if(y > x) x = y;
} inline void discrete() {
sort(in + , in + + n);
in[].val = -inf;
for(int cnt = , i = ; i <= n; i++) {
if(in[i].val != in[i - ].val) ++cnt;
chkMax(mn, cnt);
a[in[i].id] = cnt;
mp[cnt] = in[i].val;
}
} namespace PSegT {
struct Node {
int lc, rc, sum;
} s[N * ]; int root[N], nodeCnt = , top = , pool[N * ]; #define lc(p) s[p].lc
#define rc(p) s[p].rc
#define sum(p) s[p].sum
#define mid ((l + r) >> 1) inline void push(int x) {
pool[++top] = x;
} inline int newNode() {
if(top) return pool[top--];
else return ++nodeCnt;
} void ins(int &p, int l, int r, int x) {
if(!p) p = newNode();
++sum(p);
if(l == r) return; if(x <= mid) ins(lc(p), l, mid, x);
else ins(rc(p), mid + , r, x);
} int go(int p, int l, int r, int x) {
if(l == r) return sum(p); if(x <= mid) return go(lc(p), l, mid, x);
else return go(rc(p), mid + , r, x);
} int query(int p, int l, int r, int k) {
if(l == r) return mp[l];
int now = sum(lc(p)); if(k <= now) return query(lc(p), l, mid, k);
else return query(rc(p), mid + , r, k - now);
} int merge(int u, int v, int l, int r) {
if(!u || !v) return u + v; int p = newNode();
if(l == r) sum(p) = sum(u) + sum(v);
else {
lc(p) = merge(lc(u), lc(v), l, mid);
rc(p) = merge(rc(u), rc(v), mid + , r);
sum(p) = sum(lc(p)) + sum(rc(p));
} push(u), push(v);
return p;
} } using namespace PSegT; inline void init() {
for(int i = ; i <= n; i++) {
ufs[i] = i;
siz[i] = ;
ins(root[i], , mn, a[i]);
}
} int find(int x) {
return ufs[x] == x ? x : ufs[x] = find(ufs[x]);
} inline void merge(int x, int y) {
int fx = find(x), fy = find(y);
if(fx == fy) return;
root[fx] = merge(root[fx], root[fy], , mn);
ufs[fy] = fx;
siz[fx] += siz[fy]; /* for(int i = 1; i <= mn; i++)
printf("%d ", go(root[fx], 1, mn, i));
printf("\n"); */
} int main() {
read(n), read(m), read(qn);
for(int i = ; i <= n; i++) {
read(a[i]);
in[i].val = a[i], in[i].id = i;
}
for(int i = ; i <= m; i++)
read(path[i].u), read(path[i].v), read(path[i].val);
for(int i = ; i <= qn; i++)
read(q[i].pos), read(q[i].val), read(q[i].k), q[i].id = i; sort(path + , path + + m), sort(q + , q + + qn); /* printf("\n");
for(int i = 1; i <= m; i++)
printf("%d %d %d\n", path[i].u, path[i].v, path[i].val);
printf("\n");
for(int i = 1; i <= qn; i++)
printf("%d %d %d\n", q[i].pos, q[i].val, q[i].k);
printf("\n"); */ discrete();
init(); /* for(int i = 1; i <= n; i++)
printf("%d ", a[i]);
printf("\n"); */ for(int j = , i = ; i <= qn; i++) {
for(; j <= m && path[j].val <= q[i].val; ++j)
merge(path[j].u, path[j].v);
int now = find(q[i].pos); /* for(int k = 1; k <= mn; k++)
printf("%d ", go(root[now], 1, mn, k));
printf("\n"); */ if(q[i].k > siz[now]) q[q[i].id].res = -;
else q[q[i].id].res = query(root[now], , mn, siz[now] - q[i].k + );
} for(int i = ; i <= qn; i++)
printf("%d\n", q[i].res); return ;
}
Luogu 4197 Peaks的更多相关文章
- [luogu P4197] Peaks 解题报告(在线:kruskal重构树+主席树 离线:主席树+线段树合并)
题目链接: https://www.luogu.org/problemnew/show/P4197 题目: 在Bytemountains有N座山峰,每座山峰有他的高度$h_i$.有些山峰之间有双向道路 ...
- Luogu P4197 Peaks
题目链接 \(Click\) \(Here\) 做法:\(Kruskal\)重构树上跑主席树 构造方法:把每条边拆出来成一个点,点权是原先的边权.每次连边的时候,连的不再是点,而是其原先点所在的联通块 ...
- kruscal重构树略解
我们先看一道题:Luogu P4197 Peaks 这道题珂以用启发式合并+主席树来做 那么强制在线呢?(bzoj 3551 [ONTAK2010]Peaks加强版) 离线做法就不行了 我们就要用一个 ...
- [BZOJ3551]Peaks
[BZOJ3551]Peaks BZOJ luogu 建Kruskal重构树,点权为边权 按dfn序建出主席树 倍增找到能跳到的最浅的祖先 主席树查询一下 #include<bits/stdc+ ...
- Luogu 魔法学院杯-第二弹(萌新的第一法blog)
虽然有点久远 还是放一下吧. 传送门:https://www.luogu.org/contest/show?tid=754 第一题 沉迷游戏,伤感情 #include <queue> ...
- luogu p1268 树的重量——构造,真正考验编程能力
题目链接:http://www.luogu.org/problem/show?pid=1268#sub -------- 这道题费了我不少心思= =其实思路和标称毫无差别,但是由于不习惯ACM风格的题 ...
- 【BZOJ-3545&3551】Peaks&加强版 Kruskal重构树 + 主席树 + DFS序 + 倍增
3545: [ONTAK2010]Peaks Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1202 Solved: 321[Submit][Sta ...
- [luogu P2170] 选学霸(并查集+dp)
题目传送门:https://www.luogu.org/problem/show?pid=2170 题目描述 老师想从N名学生中选M人当学霸,但有K对人实力相当,如果实力相当的人中,一部分被选上,另一 ...
- [luogu P2647] 最大收益(贪心+dp)
题目传送门:https://www.luogu.org/problem/show?pid=2647 题目描述 现在你面前有n个物品,编号分别为1,2,3,--,n.你可以在这当中任意选择任意多个物品. ...
随机推荐
- @angular/cli项目构建--interceptor
JWTInterceptor import {Injectable} from '@angular/core'; import {HttpEvent, HttpHandler, HttpInterce ...
- Python文件练习
练习内容: 使用Python管理ini文件:实现查询,添加,删除,保存操作. 练习目的: 1.掌握文件基本操作 2.认识ini文件 3.了解ConfigParser: ini配置文件格式: 节:[se ...
- 《zero to one》读后感
五一放假,赶上下雨,天气很凉爽,这种天气很舒服,不冷不热,听着滴答的雨声,看看书其实也不错. 约了两个同学吃了顿饭,然后决定窝在实验室了,最近看了彼得.蒂尔的<zero to one>,确 ...
- vim直接编辑远程文件
本文由Suzzz原创,发布于http://www.cnblogs.com/Suzzz/p/4116341.html,转载请保留此声明. Linux环境下 vim scp://user@hostIP/P ...
- poj 3539 Elevator——同余类bfs
题目:http://poj.org/problem?id=3539 考虑把层数分为模a剩余系.同类内可通过+若干个a走到. 不同类之间需要通过+b.+c来走到. 需要求出每一类中最小的能走到的.即最短 ...
- 第十篇 javascript基础语法
1)基本概念 a) 语句(statement)是为了完成某种任务而进行的操作,语句以分号结尾,一个分号就表示一个语句结束.:如:var a = 1; b) 表达式(expression),指一个为了得 ...
- c++11之三: sizeof运算符 auto的优势 __func__预定义标识符
在C++11中,对非静态成员变量使用sizeof操作是合法的. auto推导的一个最大优势就是在拥有初始化表达式的复杂类型变量声明时简化代码.如:std:vector<std::string&g ...
- StringBuilder、StringBuffer、String区别
相信大家对 String 和 StringBuffer 的区别也已经很了解了,但是估计还是会有很多同志对这两个类的工作原理有些不清楚的地方,今天重新把这个概念给大家复习一下,顺便牵出 J2 ...
- ISE(Iris Server Engine)是一个基于现代C++的跨平台(Linux和Windows)框架
ISE(Iris Server Engine)是一个基于现代C++的跨平台(Linux和Windows)的高性能多线程并发网络服务器程序框架.它封装了琐碎的socket以及各种操作系统APIs,以面向 ...
- Java-API:java.io百科
ylbtech-Java-API:java.io百科 Java的核心库java.io提供了全面的IO接口.包括:文件读写.标准设备输出等.Java中IO是以流为基础进行输入输出的,所有数据被串行化写入 ...