P4197 Peaks [Kruskal 重构树 + 主席树]

2024-01-30 02:08

本文主要是介绍P4197 Peaks [Kruskal 重构树 + 主席树],希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

传送门

从小到大排, kruskal重构 , 每次倍增找到值刚好小于等于要求的点 , 问题转化为子树内的第k大

静态子树k大, 不就是主席树吗

#include<bits/stdc++.h>
#define N 200050
#define M 500050
using namespace std;int first[N],next[M],to[M],tot;struct Node{int u,v,w;}E[M];
bool cmp(Node a,Node b){return a.w<b.w;}struct Tree{int ls,rs,val;}t[N*40];
int rt[N],siz,res;int n,m,q,cnt,h[N],b[N];
int father[N]; 
int find(int x){return x==father[x]?x:father[x]=find(father[x]);}
int fa[N][22],val[N],st[N],ed[N],sign;int read(){int cnt=0; char ch=0;while(!isdigit(ch))ch=getchar();while(isdigit(ch))cnt=cnt*10+(ch-'0'),ch=getchar();return cnt;
}void add(int x,int y){next[++tot]=first[x],first[x]=tot,to[tot]=y;}void Kruskal(){sort(E+1,E+m+1,cmp); cnt=n;for(int i=1;i<=m;i++){int x=E[i].u , y=E[i].v;int fx = find(x), fy = find(y);if(fx!=fy){val[++cnt] = E[i].w;father[fx] = father[fy] = cnt;add(cnt,fx); add(cnt,fy);}} 
}/*----------------------------------主席树-------------------------------------*/
void Build(int &x,int l,int r){x=++res;if(l==r){ t[x].val = 0; return;}int mid = (l+r) >> 1;Build(t[x].ls, l, mid);Build(t[x].rs, mid+1, r);
} 
void Insert(int &x,int last,int l,int r,int pos){x = ++res;t[x].ls = t[last].ls, t[x].rs = t[last].rs;t[x].val = t[last].val + 1; if(l==r) return;int mid = (l+r) >> 1;if(pos<=mid) Insert(t[x].ls, t[last].ls, l, mid, pos);else Insert(t[x].rs, t[last].rs, mid+1, r, pos);
}
int Quary(int x,int y,int l,int r,int k){if(l==r) return l;int mid = (l+r) >> 1;int tmp = t[t[y].rs].val - t[t[x].rs].val;if(tmp >= k) return Quary(t[x].rs,t[y].rs,mid+1,r,k);else return Quary(t[x].ls,t[y].ls,l,mid,k-tmp); 
}
void dfs(int u,int f){fa[u][0] = f;for(int i=1;i<=20;i++)fa[u][i] = fa[fa[u][i-1]][i-1];st[u] = ++sign;if(u<=n) Insert(rt[sign],rt[sign-1],1,siz,h[u]);else rt[sign] = rt[sign-1];for(int i=first[u];i;i=next[i]){int t=to[i]; dfs(t,u);} ed[u] = sign;
}
int main(){n=read(),m=read(),q=read();for(int i=1;i<=n*2;i++) father[i]=i;for(int i=1;i<=n;i++) h[i] = b[i] = read();sort(b+1,b+n+1); siz = unique(b+1,b+n+1) - (b+1);for(int i=1;i<=n;i++) h[i] = lower_bound(b+1,b+siz+1,h[i]) - b;for(int i=1;i<=m;i++){E[i].u=read(),E[i].v=read(),E[i].w=read();} Kruskal();  Build(rt[0],1,siz);dfs(cnt,0);while(q--){int v=read(),x=read(),k=read();for(int i=20;i>=0;i--)if(fa[v][i] && val[fa[v][i]]<=x) v = fa[v][i];int tmp1 = rt[st[v]-1], tmp2 = rt[ed[v]];if(t[tmp2].val - t[tmp1].val < k){ printf("-1\n"); continue;} int ans = Quary(tmp1, tmp2, 1, siz, k);printf("%d\n",b[ans]);} return 0;
}

 

这篇关于P4197 Peaks [Kruskal 重构树 + 主席树]的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/658803

相关文章

C语言-数据结构 克鲁斯卡尔算法(Kruskal)邻接矩阵存储

相比普里姆算法来说,克鲁斯卡尔的想法是从边出发,不管是理解上还是实现上都更简单,实现思路:我们先把找到所有边存到一个边集数组里面,并进行升序排序,然后依次从里面取出每一条边,如果不存在回路,就说明可以取,否则就跳过去看下一条边。其中看是否是回路这个操作利用到了并查集,就是判断新加入的这条边的两个顶点是否在同一个集合中,如果在就说明产生回路,如果没在同一个集合那么说明没有回路可以加入

Mybatis Plus快速重构真批量sql入库操作

Mybatis快速重构真批量sql入库操作 基本思路 重构mybatis默认方法saveBatch和saveOrUpdateBatch的实现 基本步骤 真批量保存实现类InsertBatchMethod真批量更新实现类MysqlInsertOrUpdateBath注册InsertBatchMethod和MysqlInsertOrUpdateBath到EasySqlInjector注册Eas

[机缘参悟-222] - 系统的重构源于被动的痛苦、源于主动的精进、源于进化与演进(软件系统、思维方式、亲密关系、企业系统、商业价值链、中国社会、全球)

目录 前言:系统的重构源于被动的痛苦、源于主动的精进、源于进化与演进 一、软件系统的重构 1、重构的定义与目的 2、重构的时机与方法 3、重构的注意事项 4、重构的案例分析 二、大脑思维的重构 1、大脑思维重构的定义 2、大脑思维重构的方法 3、大脑思维重构的挑战与前景 三、认知的重构 1、定义 2、目的 3、方法 四、实例 五、总结 四、婚姻家庭的重构 1、婚

总结如何成为“好”代码——读《重构:改善既有代码的设计》有感

读后感 说是“读后感”,其实并不是看得很仔细,尤其是各种代码例子,我基本上是跳过的。个人觉得,重构这件事上,关键是要能嗅出坏代码,知道什么是好代码,这样目标明确后,重构的手段其实是水到渠成的,唯一要注意的就是书中强调的:要以小步为单位稳打稳扎进行。 我所理解的“好”代码 核心目标 那么如何才是“好”代码?书中的答案是:“人们是否能轻而易举地修改”,而我觉得抽象层级更高的描述是:易于未来的工

数据结构 - 二叉树(重构 + 遍历)

写在前面 昨天有同学问到我一题关于重构二叉树的问题(link),做了一下,也做个记录吧! 所谓二叉树的重构,就是给你前序和中序,或者中序和后序,让你还原这棵二叉树. 注意:给出前序和后序是不能唯一确定一棵二叉树的,证明请看这儿.   一.给出前序和中序,重构二叉树 一个递归的过程: 当前结点的value:每一轮根据前序的第一个元素确定当前结点值. 左子树的中序遍历

【POJ】2104 K-th Number 静态第K小——主席树

传送门:【POJ】2104 K-th Number 题目分析: 哇咔咔,又get了一个新技能——主席树,初步学习主席树,一次AC,感觉好棒~ 也在此Orz一下发明者主席——fotile96,在叉姐群经常看到主席的身影,不过蒟蒻也只能仰望神犇的背影了,起步迟且天赋不如人,只能慢慢的走下去,希望有一天能看到另一个世界。 主席树的编程方式是函数式编程(可持久化),保证我们可以查询历史

来自Uber的12条架构重构经验

来自Uber的12条架构重构经验 2016-02-04  来源:聊聊架构 分类:架构  阅读(56) 评论(0)  对于开发者来说,架构设计是软件研发过程中最重要的一环,所谓没有图纸,就建不了房子。在遍地App的互联网时代,架构设计有了一些比较成熟的模式,开发者和架构师也可以经常借鉴。 但是,随着应用的不断发展,最初的架构往往面临着各种问题,比如无法满足客户的需求、无法实现应用的扩

重构手法之重新组织函数

重构手法之重新组织函数 在重构的手法中,很大的一部分是对函数进行整理,使函数能够恰当地包装代码(让代码自己说话而不是写更多的注释)。重新组织函数的驱动力,往往都是由于函数过长。因为函数过长就以为着包含了更多属性和逻辑,这样复杂的逻辑和诸多属性(如函数内部的局部变量或者静态变量等)会让代码变得难以维护,需要对其进行重新组织。 提炼函数 在冗长的函数中提炼出精小的函数,让每个短小函数负责的

LeetCode 重构二叉搜索数,即找出两个被交换的节点

原题:Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing its structure. Note: A solution using O(n) space is pretty straight forward. Could you de