线段树合并+离线+启发式合并

半年前这道题t成狗。。。

离线的做法比较好想,按照边的权值排序,询问的权值排序,然后枚举询问不断加边,加到上限后查找第k大值,这里平衡树,权值线段树都可以实现。

那么我们用权值线段树就行了, 并查集维护两点连通性,不连通的话就合并,并查集连接。

#include<bits/stdc++.h>
using namespace std;
const int N = ;
struct Query {
int v, x, k, id;
bool friend operator < (Query A, Query B)
{
return A.x < B.x;
}
} q[N];
struct edge {
int u, v, w;
bool friend operator < (edge A, edge B)
{
return A.w < B.w;
}
} e[N];
int n, m, Q;
int root[N], h[N], ans[N];
vector<int> vt;
map<int, int> mp;
inline int read()
{
int x = , f = ; char c = getchar();
while(c < '' || c > '') { if(c == '-') f = -; c = getchar(); }
while(c >= '' && c <= '') { x = x * + c - ''; c = getchar(); }
return x * f;
}
namespace seg
{
int cnt;
int lc[N << ], rc[N << ], size[N << ];
void update(int l, int r, int &x, int pos)
{
x = ++cnt;
++size[x];
if(l == r) return;
int mid = (l + r) >> ;
if(pos <= mid) update(l, mid, lc[x], pos);
else update(mid + , r, rc[x], pos);
}
int merge(int x, int y)
{
if(!x) return y;
if(!y) return x;
size[x] += size[y];
lc[x] = merge(lc[x], lc[y]);
rc[x] = merge(rc[x], rc[y]);
return x;
}
int query(int l, int r, int x, int rank)
{
if(l == r) return l;
int mid = (l + r) >> ;
if(size[rc[x]] >= rank) return query(mid + , r, rc[x], rank);
else return query(l, mid, lc[x], rank - size[rc[x]]);
}
} using namespace seg;
int main()
{
n = read();
m = read();
Q = read();
for(int i = ; i <= n; ++i)
{
h[i] = read();
vt.push_back(h[i]);
}
sort(vt.begin(), vt.end());
vt.erase(unique(vt.begin(), vt.end()), vt.end());
for(int i = ; i <= n; ++i)
{
h[i] = lower_bound(vt.begin(), vt.end(), h[i]) - vt.begin() + ;
update(, n, root[i], h[i]);
}
for(int i = ; i <= m; ++i)
{
e[i].u = read();
e[i].v = read();
e[i].w = read();
}
sort(e + , e + m + );
for(int i = ; i <= Q; ++i)
{
q[i].v = read();
q[i].x = read();
q[i].k = read();
q[i].id = i;
}
sort(q + , q + Q + );
int j = ;
for(int i = ; i <= Q; ++i)
{
while(e[j].w <= q[i].x && j <= m)
{
if(root[e[j].u] != root[e[j].v]) root[e[j].u] = root[e[j].v] = merge(root[e[j].u], root[e[j].v]);
++j;
}
if(size[root[q[i].v]] < q[i].k) ans[q[i].id] = -;
else ans[q[i].id] = query(, n, root[q[i].v], q[i].k);
}
for(int i = ; i <= Q; ++i) printf("%d\n", ans[i]);
return ;
}

bzoj3545的更多相关文章

  1. [您有新的未分配科技点][BZOJ3545&BZOJ3551]克鲁斯卡尔重构树

    这次我们来搞一个很新奇的知识点:克鲁斯卡尔重构树.它也是一种图,是克鲁斯卡尔算法求最小生成树的升级版首先看下面一个问题:BZOJ3545 Peaks. 在Bytemountains有N座山峰,每座山峰 ...

  2. 【BZOJ3551】【BZOJ3545】 【ONTAK2010】 Peaks (kruskal重构树+主席树)

    Description ​ 在\(Bytemountains\)有\(~n~\)座山峰,每座山峰有他的高度\(~h_i~\). 有些山峰之间有双向道路相连,共\(~m~\)条路径,每条路径有一个困难值 ...

  3. BZOJ3545 [ONTAK2010]Peaks kruskal 并查集 主席树 dfs序

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3545 题意概括 Description 在Bytemountains有N座山峰,每座山峰有他的高度 ...

  4. bzoj3545: [ONTAK2010]Peaks 重构树 主席树

    题目链接 bzoj3545: [ONTAK2010]Peaks 题解 套路重构树上主席树 代码 #include<cstdio> #include<algorithm> #de ...

  5. 【BZOJ3545】 [ONTAK2010]Peaks

    BZOJ3545 [ONTAK2010]Peaks Solution 既然会加强版,直接把强制在线的操作去掉就好了. 代码实现 #include<stdio.h> #include< ...

  6. 【bzoj3545/bzoj3551】[ONTAK2010]Peaks/加强版 Kruskal+树上倍增+Dfs序+主席树

    bzoj3545 题目描述 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询 ...

  7. bzoj3545 [ONTAK2010]Peaks、bzoj3551 [ONTAK2010]Peaks加强版

    题目描述: bzoj3545,luogu bzoj3551 题解: 重构树+线段树合并. 可以算是板子了吧. 代码(非强制在线): #include<cstdio> #include< ...

  8. 【bzoj3545】[ONTAK2010]Peaks 线段树合并

    [bzoj3545][ONTAK2010]Peaks 2014年8月26日3,1512 Description 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路 ...

  9. 「BZOJ3545」「ONTAK2010」Peaks

    「BZOJ3545」「ONTAK2010」Peaks 题目传送门 题目大意: 给定一个 \(n\) 个点,\(m\) 条边的带点权边权无向图,有 \(q\) 次询问,每次询问从 \(v\) 点出发,经 ...

  10. bzoj3545/bzoj3551 [ONTAK2010]Peaks/Peaks加强版

    bzoj3545/bzoj3551 [ONTAK2010]Peaks/Peaks加强版 传送门:bzoj  bzoj wdnmd为什么加强版不是权限题原题却是啊 3545: [ONTAK2010]Pe ...

随机推荐

  1. 用sed写配置IP脚本参数

    #!/bin/bash#配置ip地址参数脚本NET=/etc/sysconfig/network-scripts/ifcfg-ens33if grep -E "BOOTPROTO=dhcp& ...

  2. 由杭州开往成都的K529次列车

    春运期间,在由杭州开往成都的K529次列车上,旅客严重超员.一个靠窗坐着的老大爷正跟邻座的人分享他的幸运经历,原来,他是到上饶的,买的是无座票,上车后抱着侥幸心理事先占了个好座,没想到直到开车也没人上 ...

  3. 洛谷——P3946 ことりのおやつ(小鸟的点心)

    P3946 ことりのおやつ(小鸟的点心) 题目太长,请去链接里看吧 注意细节:特判终点(即使困住又能怎样,到达就好了),特判高度 #include<bits/stdc++.h> #defi ...

  4. C++STL快速入门学习

    C++ STL中最基本以及最常用的类或容器无非就是以下几个: string vector set list map 下面就依次介绍一下它们,并给出一些最常见的使用方法,做到最快入门. string 首 ...

  5. UVA-1599 Ideal Path(双向BFS)

    题目: 给一个n个点m条边(2≤m≤100000, 1≤m≤200000)的无向图,每条边上都涂有一种颜色(用1到1000000000表示).求从结点1到结点n的一条路径, 使得经过的边数尽量少,在此 ...

  6. linux strings-在对象文件或二进制文件中查找可打印的字符串

    推荐:更多Linux 文件查找和比较 命令关注:linux命令大全 strings命令在对象文件或二进制文件中查找可打印的字符串.字符串是4个或更多可打印字符的任意序列,以换行符或空字符结束. str ...

  7. JSP内置对象说明

    JSP内置对象说明 制作人:全心全意 request对象:request对象封装了由客户端生成的HTTP请求的所有细节,主要包括HTTP头信息.系统信息.请求方式和请求参数等.通过request对象提 ...

  8. ubuntu 安装codeblocks13.12

    通过添加PPA的方法安装: sudo add-apt-repository ppa:pasgui/ppa sudo apt-get update sudo apt-get install codebl ...

  9. js之获取html标签的值

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. String与StringBuffer,StringBuilder

    在java中有3个类来负责字符的操作. 1.Character 是进行单个字符操作的, 2.String 对一串字符进行操作.不可变类. 3.StringBuffer 也是对一串字符进行操作,但是可变 ...