题意

题目链接

往后中文题就不翻译了qwq

Sol

又是码农题。。出题人这是强行把Kruskal重构树和主席树拼一块了啊。。

首先由于给出的限制条件是<=x,因此我们在最小生成树上走一定是最优的。

考虑把Kruskal重构树建出来,重构树上每个新的节点代表的是边权,同时用倍增数组维护出跳2^i步后能走到的值最大的节点

这样,该节点的整个子树内的节点都是可以走到的。

用dfs序+主席树维护出每个节点内H的值,直接查第K大即可

需要注意的是,对于不在原树内的节点,H要设的非常小,或者不插入,以免对答案产生影响

同时H需要离散化

写+调用了整两个小时,,自己的码力还是太弱了qwq

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#define Pair pair<int, int>
#define MP(x, y) make_pair(x, y)
#define fi first
#define se second
using namespace std;
const int MAXN = 1e6 + ;
inline int read() {
char c = getchar(); int x = , f = ;
while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * f;
}
int N, M, Q, H[MAXN], date[MAXN], tot, num = ;
struct Edge {
int u, v, w;
bool operator < (const Edge &rhs) const {
return w < rhs.w;
}
}E[MAXN];
void AddEdge(int x, int y, int z) {E[++num] = (Edge) {x, y, z};}
int fa[MAXN], fd[MAXN][], dis[MAXN][];
int find(int x) {
if(fa[x] == x) return fa[x];
else return fa[x] = find(fa[x]);
}
int unionn(int x, int y) {fa[x] = y;}
vector<int> v[MAXN];
void Build() {
for(int i = ; i <= (N << ); i++) fa[i] = i;
sort(E + , E + num + );
for(int i = ; i <= num; i++) {
int x = E[i].u, y = E[i].v, w = E[i].w;
int fx = find(x), fy = find(y);
if(fx == fy) continue;
tot++;
fa[fx] = tot; fa[fy] = tot;
v[fx].push_back(tot); v[fy].push_back(tot);
v[tot].push_back(fx); v[tot].push_back(fy);
dis[fx][] = w; dis[fy][] = w;
fd[fx][] = tot; fd[fy][] = tot;
if(tot == * N - ) break;
}
}
int ls[MAXN * ], rs[MAXN * ], Tsiz[MAXN * ], root[MAXN], cnt, siz[MAXN], dfn[MAXN], tra[MAXN];
void dfs(int x, int fa) {
dfn[x] = ++cnt; tra[dfn[x]] = x; siz[x] = ;
for(int i = ; i < v[x].size(); i++) {
int to = v[x][i];
if(to == fa) continue;
dfs(to, x);
siz[x] += siz[to];
}
}
void update(int k) {
Tsiz[k] = Tsiz[ls[k]] + Tsiz[rs[k]];
}
void Insert(int &k, int p, int val, int l, int r) {
k = ++cnt;
ls[k] = ls[p]; rs[k] = rs[p]; Tsiz[k] = Tsiz[p];
if(val == -) return ;
Tsiz[k]++;
if(l == r) return ;
int mid = l + r >> ;
if(val <= mid) Insert(ls[k], ls[p], val, l, mid);
else Insert(rs[k], rs[p], val, mid + , r);
update(k);
}
void MakeTree() {
cnt = ;
for(int i = ; i <= tot; i++)
Insert(root[i], root[i - ], H[tra[i]], , N);
}
void Jump() {
for(int j = ; j <= ; j++) {
for(int i = ; i <= tot; i++) {
fd[i][j] = fd[fd[i][j - ]][j - ];
dis[i][j] = max(dis[fd[i][j - ]][j - ], dis[i][j - ]);
}
}
}
int Get(int x, int val) {
for(int i = ; i >= ; i--)
if(dis[x][i] <= val && fd[x][i] != )
x = fd[x][i];
return x;
}
int Query(int lt, int rt, int k, int l, int r) {
int used = Tsiz[rs[rt]] - Tsiz[rs[lt]];
if(l == r) {
if(Tsiz[rt] - Tsiz[lt] < k) return -;
else return l;
}
int mid = l + r >> ;
if(k <= used) return Query(rs[lt], rs[rt], k, mid + , r);
else return Query(ls[lt], ls[rt], k - used, l, mid);
}
main() {
//freopen("1.in", "r", stdin);
//freopen("a.out", "w", stdout);
tot = N = read(); M = read(); Q = read();
memset(H, -, sizeof(H));
for(int i = ; i <= N; i++) H[i] = read(), date[i] = H[i];
sort(date + , date + N + );
int tmp = unique(date + , date + N + ) - date - ;
for(int i = ; i <= N; i++) H[i] = lower_bound(date + , date + N + , H[i]) - date;
for(int i = ; i <= M; i++) {
int x = read(), y = read(), z = read();
// v[x].push_back(MP(y, z));
// v[y].push_back(MP(x, z));
AddEdge(x, y, z); AddEdge(y, x, z);
}
Build();
dfs(tot, );
MakeTree();
Jump();
while(Q--) {
int v = read(), x = read(), k = read();
int top = Get(v, x);
int l = dfn[top], r = dfn[top] + siz[top] - ;
int ans = Query(root[l], root[r], k, , N);
if(ans == -) printf("%d\n", -);
else printf("%d\n", date[ans]);
}
return ;
}

洛谷P4197 Peaks(Kruskal重构树 主席树)的更多相关文章

  1. BZOJ3545&3551[ONTAK2010]Peaks——kruskal重构树+主席树+dfs序+树上倍增

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

  2. luogu4197 Peaks (kruskal重构树+主席树)

    按照边权排序建出kruskal重构树,每次就变成了先找一个权值<=x的最远的祖先,然后看这个子树的第k小.离散化一下,在dfs序上做主席树即可 而且只需要建叶节点的主席树 注意输出的是第k小点的 ...

  3. 【BZOJ3545】Peaks(Kruskal重构树 主席树)

    题目链接 大意 给出有\(N\)个点\(M\)条边的一张图,其中每个点都有一个High值,每条边都有一个Hard值. 再给出\(Q\)个询问:\(v\) \(x\) \(k\) 每次询问查询从点\(v ...

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

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

  5. luoguP4197:Peaks(Kruskal重构树+主席树)或者(点分树+离线)

    题意:有N座山,M条道路.山有山高,路有困难值(即点权和边权).现在Q次询问,每次给出(v,p),让求从v出发,只能结果边权<=p的边,问能够到达的山中,第K高的高度(从大到小排序). 思路:显 ...

  6. [luogu P4197] Peaks 解题报告(在线:kruskal重构树+主席树 离线:主席树+线段树合并)

    题目链接: https://www.luogu.org/problemnew/show/P4197 题目: 在Bytemountains有N座山峰,每座山峰有他的高度$h_i$.有些山峰之间有双向道路 ...

  7. 【BZOJ-3545&3551】Peaks&加强版 Kruskal重构树 + 主席树 + DFS序 + 倍增

    3545: [ONTAK2010]Peaks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1202  Solved: 321[Submit][Sta ...

  8. [BZOJ3551][ONTAK2010]Peaks(加强版)(Kruskal重构树,主席树)

    3551: [ONTAK2010]Peaks加强版 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2438  Solved: 763[Submit][ ...

  9. LOJ.2865.[IOI2018]狼人(Kruskal重构树 主席树)

    LOJ 洛谷 这题不就是Peaks(加强版)或者归程么..这算是\(IOI2018\)撞上\(NOI2018\)的题了? \(Kruskal\)重构树(具体是所有点按从小到大/从大到小的顺序,依次加入 ...

随机推荐

  1. Spring—Ioc

    IoC容器,最主要的就是完成对象的创建以及维护对象的依赖关系等. 所谓控制反转,包括两部分:一是控制,二是反转,就是把传统方式需要由代码来实现对象的创建.维护对象的依赖关系,反转给容器来帮忙管理和实现 ...

  2. SAMBA服务器的安装和配置实践

    实验需求:1) 使用RPM包安装samba服务 2) 实现匿名访问,验证可以读写文件.目录 3) 实现指定用户的访问 4) 实现指定用户的访问,并为用户赋予不同的权限 启动LINUX系统,进行SAMB ...

  3. Linux proc 内存

    ps: USER      PID    %CPU %MEM   VSZ   RSS  TTY  STAT  START  TIME  COMMAND root          4238     0 ...

  4. 两步实现在Git Bash中用Sublime打开文件

    每次都要用鼠标点来点去才能用sublime打开文件!太不科学!今天来配置一下在Git bash中用sublime打开文件 方法 新建一个文件命名为你想要的命令,比如 subl(注意不能有后缀名),内容 ...

  5. 隐藏Apche、Nginx、PHP的版本号提高网站安全性

    隐藏Apache版本号 在apache配置文件httpd.conf中,加入以下代码 ServerTokens Prod ServerSignature Off 隐藏Nginx版本号 在nginx的配置 ...

  6. java实验五20145204

    java实验 Tcp传输 实验内容 运行代码一人服务器,一人客户端. 下载加解密代码,先编译运行代码,一人加密一人解密,适当修改代码. 集成代码,一人加密后通过TCP发送,加密使用AES或DES,AE ...

  7. HDU 5934 Bomb(tarjan/SCC缩点)题解

    思路:建一个有向图,指向能引爆对象,把强连通分量缩成一点,只要点燃图中入度为0的点即可.因为入度为0没人能引爆,不为0可以由别人引爆. 思路很简单,但是早上写的一直错,改了半天了,推倒重来才过了... ...

  8. centos 升级python26到python27

    由于开发库依赖于python27,而自己安装的centos6.8自带的python是2.6.6,因此打算简单的做一下升级. 因为centos的yum依赖于python26因此不打算覆盖26.步骤如下: ...

  9. python 进制转换

    print hex(),hex(-) #转换成十六进制 print oct(),oct(-) #转换成八进制 print bin(),bin(-) #转换成二进制 print int("字面 ...

  10. Android ViewGroup等容器控件的使用

    在Android中,可以自定义类,继承ViewGroup等容器类,以实现自己需要的布局显示.如果你在ViewGroup中增加了控件,却无法显示出 来,那么下面这个例子,就可以用来参考了.(主要是要实现 ...