洛谷P4197 Peaks(Kruskal重构树 主席树)_weixin_33857230的博客-程序员宝宝

题意

题目链接

往后中文题就不翻译了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 + 10;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {
    if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int N, M, Q, H[MAXN], date[MAXN], tot, num = 0;
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][22], dis[MAXN][22];
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 = 1; i <= (N << 1); i++) fa[i] = i;
    sort(E + 1, E + num + 1);
    for(int i = 1; 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][0] = w; dis[fy][0] = w;
        fd[fx][0] = tot; fd[fy][0] = tot;
        if(tot == 2 * N - 1) break;
    }
}
int ls[MAXN * 30], rs[MAXN * 30], Tsiz[MAXN * 30], root[MAXN], cnt, siz[MAXN], dfn[MAXN], tra[MAXN];
void dfs(int x, int fa) {
    dfn[x] = ++cnt; tra[dfn[x]] = x; siz[x] = 1;
    for(int i = 0; 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 == -1) return ;
    Tsiz[k]++;
    if(l == r) return ;
    int mid = l + r >> 1;
    if(val <= mid) Insert(ls[k], ls[p], val, l, mid);
    else Insert(rs[k], rs[p], val, mid + 1, r);
    update(k);
}
void MakeTree() {
    cnt = 0;
    for(int i = 1; i <= tot; i++) 
        Insert(root[i], root[i - 1], H[tra[i]], 1, N);
}
void Jump() {
    for(int j = 1; j <= 21; j++) {
        for(int i = 1; i <= tot; i++) {
            fd[i][j] = fd[fd[i][j - 1]][j - 1];
            dis[i][j] = max(dis[fd[i][j - 1]][j - 1], dis[i][j - 1]);
        }
    }
}
int Get(int x, int val) {
    for(int i = 21; i >= 0; i--) 
        if(dis[x][i] <= val && fd[x][i] != 0) 
            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 -1;
        else return l;
    } 
    int mid = l + r >> 1;
    if(k <= used) return Query(rs[lt], rs[rt], k, mid + 1, 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, -1, sizeof(H));
    for(int i = 1; i <= N; i++) H[i] = read(), date[i] = H[i];
    sort(date + 1, date + N + 1);
    int tmp = unique(date + 1, date + N + 1) - date - 1;
    for(int i = 1; i <= N; i++) H[i] = lower_bound(date + 1, date + N + 1, H[i]) - date;
    for(int i = 1; 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, 0);
    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] - 1;
        int ans = Query(root[l], root[r], k, 1, N);
        if(ans == -1) printf("%d\n", -1);
        else printf("%d\n", date[ans]);
    }
    return 0;
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_33857230/article/details/86016056

智能推荐

系统安全及应用_xinheng233的博客-程序员宝宝

系统安全及应用账号安全控制系统账号清理密码安全控制su命令切换用户PAM认证的构成PAM安全用户PAM可插拔式认证模块PAM认证原理PAM安全认证流程使用sudo机制提升权限配置sudo授权查看sudo操作记录查询授权的sudo操作统引导和登陆控制调整BIOS引导设置开关机安全控制GRUB限制简要操作具体操作终端登陆安全控制系统弱口令检测Joth the Ripper ,简称JR安装JR工具检测弱口令账号密码文件的暴力破解具体步骤端口扫描网络扫描:NMAPNMAP常用的选项和扫描类型查看本机开放的端口检测主

微波工程基础_军工央企丨上海微波设备研究所_weixin_39523529的博客-程序员宝宝

上海微波设备研究所上海微波设备研究所(中国电子科技集团公司第五十一研究所)成立于1978年,主要从事电子对抗专业基础技术研究和设备研制,属于军工一类整机研究所,一类事业单位,是我国雷达对抗骨干研究单位之一。上海微波设备研究所设有7个研发部门,1个装备制造部门、1个基础研究室,1个生产部门及2个控股公司。地处上海市嘉定区南翔镇,与著名的明朝园林、上海市十大名园——“古猗园”相邻,紧靠轻轨1...

Banner框架_大伟伟的博客-程序员宝宝

Banner是一个框架,此框架是用于实现在Android中,ViewPager的图片无限轮播功能。在使用Banner框架时我们需要添加它的远程依赖:compile ‘com.youth.banner:banner:1.4.9’compile 'com.youth.banner:banner:1.4.9'11、添加依赖 (1)、点击代码编辑页面右边的Grable;然后选择要添加远程依赖的项目...

redis5.0版本集群移除节点_redis 5.0集群移除节点_吖苏哥哥好的博客-程序员宝宝

redis 集群多了之后,发现现在的有些节点有些多余没用,或者达不到用那么多节点的情况,那么就可以进行 节点的移除, 5.0 版本由于不用 ruby 进行集群操作了,所以方式跟5.0以前有很多不同的地方我以我机器上的 7008 节点为例首先登录集群, 使用 cluster nodes 查看信息获取到 7008 节点的ID(红圈中前面8f111b3074341e145105d70...

VnlnHub BOREDHACKERBLOG SOCIAL NETWORK 2.0_vninhub_奋斗吧!小胖子的博客-程序员宝宝

Vnlnhub BOREDHACKERBLOG SOCIAL NETWORK 2.0靶机过关攻略记录,设计知识包括:端口服务探测、sql注入、文件上传漏洞、linux本地提权、密码爆破、漏洞利用(python XMLRPC服务)、利用代码编写、gdb程序调试、缓冲区溢出漏洞利用等

随便推点

jQuery中json字符串转换为json对象_weixin_30498807的博客-程序员宝宝

在进行web开发,经常需要将服务器返回到客户端的json字符串转换为json对象,下面介绍三种方法:通过easyUI的form组件小例子说明:$(function(){$("#form").form('submit',{url:'服务器端处理的url地址',success:function (data) { //注意:此时的data只是一个普通的json字符...

如何使用Keras fit和fit_generator(动手教程)_Chevalier~的博客-程序员宝宝

写在前面原文出处请点击这里被Adrian Rosebrock圈粉后,就一直期待他的更新,作者每周一更新,考虑到时差问题(作者在美国),一般北京时间周二才能看到。作者根据读者留言中的问题写下了这篇博客,迫不及待的学习了一番,发现过一遍是无法完全理解的,还需要重复...

pktgen工具使用及案例整理_pktgen参数_风清之雷的博客-程序员宝宝

pktgen工具使用及案例整理1、pktgen工具命令说明1.1、pktgen控制命令pktgen命令参数参数说明start所有的线程开始发送stop停止1.2、线程的控制命令pktgen命令参数参数说明add_device添加某个端口到某个线程rem_device_all删除绑定在某个线程的所有端口max_befor...

设计模式-外观模式_chenjianqing1983的博客-程序员宝宝

外观模式(Facade Pattern) 为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。 将一个系统划分成为若干个子系统有利于降低系统的复杂性。一个常见的设计目标是使子系统间的通信和相互依赖关系达到最小。达到该目标的途径之...

小工具——寻找节点的一二三阶邻居_一阶邻居_7:45am的博客-程序员宝宝

日常小工具,本人代码水平一般,只是存在这里当笔记。若正好有小伙伴用到,希望能帮助到你,如若有错误之处,欢迎批评指正。输入:图以及图中一个节点输出:该节点在图中的一阶,二阶,三阶邻居import networkx as nxdef find123Nei(G, node): nodes = list(nx.nodes(G)) nei1_li = [] nei2_li = [] nei3_li = [] for FNs in list(nx.neighbors(G

怎样把本地的jar包引入到maven工程里面_weixin_30379973的博客-程序员宝宝

有些jar包在maven库里面查找不到,但是maven项目又有用到,此时最简单的方法就是把该jar包放到工程底下某个目录,然后在pom.xml里面配置dependency引入它。 具体如何操作呢? 假如我们需要引入taobao-sdk-java-auto_1416460582369-20151123.jar这个jar包。 首先将该jar包放到/install/libs目录,例如: 其次,修改po...

推荐文章

热门文章

相关标签