BZOJ3551 Peaks加强版 [Kruskal重构树,主席树]
思路
我觉得这题可持久化线段树合并也可以做
我觉得这题建出最小生成树之后动态点分治+线段树也可以做
还是学习一下Kruskal重构树吧……
Kruskal重构树,就是在做最小生成树的时候,如果一条边\(e\)被选中了,就让那两个连通块的根都连向它,变成新的根。显然,最后会做出一个二叉树,其中叶子是点、非叶子节点是边,且边权形成了一个堆的形式。
分析一下性质,发现“用不超过某个权值的边构成的连通块”其实就是从一个点往上跳,最后的某一棵子树。
于是倍增+主席树区间k大,这题就做完了。
Kruskal重构树的例题还有[NOI2018]归程。只要知道这个东西那题似乎就一sb题……
代码
#include<bits/stdc++.h>
//clock_t t=clock();
namespace my_std{
using namespace std;
// #define pii pair<int,int>
// #define fir first
// #define sec second
// #define MP make_pair
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define drep(i,x,y) for (int i=(x);i>=(y);i--)
#define go(x) for (int i=head[x];i;i=edge[i].nxt)
// #define templ template<typename T>
#define sz 606060
typedef long long ll;
typedef double db;
// mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
// templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
// templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
// templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
inline void read(int& t)
{
t=0;char f=0,ch=getchar();double d=0.1;
while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
t=(f?-t:t);
}
// template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
// char __sr[1<<21],__z[20];int __C=-1,__zz=0;
// inline void Ot(){fwrite(__sr,1,__C+1,stdout),__C=-1;}
// inline void print(register int x)
// {
// if(__C>1<<20)Ot();if(x<0)__sr[++__C]='-',x=-x;
// while(__z[++__zz]=x%10+48,x/=10);
// while(__sr[++__C]=__z[__zz],--__zz);__sr[++__C]='\n';
// }
// void file()
// {
// #ifdef NTFOrz
// freopen("a.in","r",stdin);
// #endif
// }
// inline void chktime()
// {
// #ifndef ONLINE_JUDGE
// cout<<(clock()-t)/1000.0<<'\n';
// #endif
// }
// #ifdef mod
// ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
// ll inv(ll x){return ksm(x,mod-2);}
// #else
// ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
// #endif
// inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std;
int n,m,Q;
int val[sz],V[sz];
struct hhh{int u,v,w;const bool operator < (const hhh &x) const {return w<x.w;}}e[sz];
struct hh{int t,nxt;}edge[sz<<1];
int head[sz],ecnt;
void make_edge(int f,int t)
{
edge[++ecnt]=(hh){t,head[f]};
head[f]=ecnt;
edge[++ecnt]=(hh){f,head[t]};
head[t]=ecnt;
}
int rt;
int fa[sz][25],dfn[sz],low[sz],id[sz],T;
#define v edge[i].t
void dfs(int x,int f)
{
id[dfn[x]=++T]=x;
fa[x][0]=f;
rep(i,1,20) fa[x][i]=fa[fa[x][i-1]][i-1];
go(x) if (v!=f) dfs(v,x);
low[x]=T;
}
#undef v
int f[sz];
int getfa(int x){return x==f[x]?x:f[x]=getfa(f[x]);}
void merge(int x,int y){f[x]=y;make_edge(x,y);}
int root[sz];
#define Tree sz*4
int size[Tree],ls[Tree],rs[Tree],cnt;
#undef Tree
#define lson ls[k],l,mid
#define rson rs[k],mid+1,r
void insert(int &k,int l,int r,int x,int pre)
{
k=++cnt;size[k]=size[pre]+1;ls[k]=ls[pre],rs[k]=rs[pre];
if (l==r) return;
int mid=(l+r)>>1;
if (x<=mid) insert(lson,x,ls[pre]);
else insert(rson,x,rs[pre]);
}
int query(int k1,int k2,int l,int r,int K)
{
if (l==r) return l;
int mid=(l+r)>>1,S=size[rs[k2]]-size[rs[k1]];
if (S>=K) return query(rs[k1],rs[k2],mid+1,r,K);
return query(ls[k1],ls[k2],l,mid,K-S);
}
int main()
{
// file();
read(n),read(m),read(Q);
rep(i,1,n) read(val[i]),V[i]=val[i];
sort(V+1,V+n+1);int _n=unique(V+1,V+n+1)-V-1;
rep(i,1,n) val[i]=lower_bound(V+1,V+_n+1,val[i])-V;
int x,y,z;
rep(i,1,m) read(x),read(y),read(z),e[i]=(hhh){x,y,z};
sort(e+1,e+m+1);
rep(i,1,n+m) f[i]=i;
rep(i,1,m)
{
x=e[i].u,y=e[i].v;
x=getfa(x),y=getfa(y);
if (x==y) continue;
merge(x,i+n),merge(y,i+n);
}
rt=getfa(1);
dfs(rt,0);
rep(i,1,n+n-1) if (id[i]<=n) insert(root[i],1,n,val[id[i]],root[i-1]); else root[i]=root[i-1];
int ans=-1;
while (Q--)
{
read(x),read(y),read(z);
if (ans!=-1) x^=ans,y^=ans,z^=ans;
drep(i,20,0) if (fa[x][i]&&e[fa[x][i]-n].w<=y) x=fa[x][i];
if (size[root[low[x]]]-size[root[dfn[x]-1]]<z) ans=-1;
else ans=V[query(root[dfn[x]-1],root[low[x]],1,n,z)];
printf("%d\n",ans);
}
return 0;
}
BZOJ3551 Peaks加强版 [Kruskal重构树,主席树]的更多相关文章
- [BZOJ3551][ONTAK2010]Peaks(加强版)(Kruskal重构树,主席树)
3551: [ONTAK2010]Peaks加强版 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 2438 Solved: 763[Submit][ ...
- 【BZOJ-3545&3551】Peaks&加强版 Kruskal重构树 + 主席树 + DFS序 + 倍增
3545: [ONTAK2010]Peaks Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1202 Solved: 321[Submit][Sta ...
- BZOJ.3551.[ONTAK2010]Peaks加强版(Kruskal重构树 主席树)
题目链接 \(Description\) 有n个座山,其高度为hi.有m条带权双向边连接某些山.多次询问,每次询问从v出发 只经过边权<=x的边 所能到达的山中,第K高的是多少. 强制在线. \ ...
- luoguP4197:Peaks(Kruskal重构树+主席树)或者(点分树+离线)
题意:有N座山,M条道路.山有山高,路有困难值(即点权和边权).现在Q次询问,每次给出(v,p),让求从v出发,只能结果边权<=p的边,问能够到达的山中,第K高的高度(从大到小排序). 思路:显 ...
- BZOJ 3551: [ONTAK2010]Peaks加强版 [Kruskal重构树 dfs序 主席树]
3551: [ONTAK2010]Peaks加强版 题意:带权图,多组询问与一个点通过边权\(\le lim\)的边连通的点中点权k大值,强制在线 PoPoQQQ大爷题解传送门 说一下感受: 容易发现 ...
- 【BZOJ 3551】[ONTAK2010] Peaks加强版 Kruskal重构树+树上倍增+主席树
这题真刺激...... I.关于Kruskal重构树,我只能开门了,不过补充一下那玩意还是一棵满二叉树.(看一下内容之前请先进门坐一坐) II.原来只是用树上倍增求Lca,但其实树上倍增是一种方法,L ...
- BZOJ 3551: [ONTAK2010]Peaks加强版 Kruskal重构树+dfs序+主席树+倍增
建出来 $Kruskal$ 重构树. 将询问点向上跳到深度最小,且合法的节点上. 那么,得益于重构树优美的性质,这个最终跳到的点为根的所有子节点都可以与询问点互达. 对于子树中求点权第 $k$ 大的问 ...
- BZOJ3545&3551[ONTAK2010]Peaks——kruskal重构树+主席树+dfs序+树上倍增
题目描述 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只 ...
- luogu4197 Peaks (kruskal重构树+主席树)
按照边权排序建出kruskal重构树,每次就变成了先找一个权值<=x的最远的祖先,然后看这个子树的第k小.离散化一下,在dfs序上做主席树即可 而且只需要建叶节点的主席树 注意输出的是第k小点的 ...
随机推荐
- 广度优先搜索(BFS)思路及算法分析
1.算法用途: 是一种图像搜索演算法.用于遍历图中的节点,有些类似于树的深度优先遍历.这里唯一的问题是,与树不同,图形可能包含循环,因此我们可能会再次来到同一节点. 2.主要思想: 主要借助一个队列. ...
- 【转载】C#中List集合使用Exists方法判断是否存在符合条件的元素对象
在C#的List集合操作中,有时候需要根据条件判断List集合中是否存在符合条件的元素对象,此时就可以使用List集合的扩展方法Exists方法来实现,Exists方法的签名为bool Exists( ...
- JavaWeb开发回顾总结【不断更新中】
1.Java语言编程 2.Servlet & JSP(JavaServer Pages) JSPGet方法中文乱码,以上是我的一篇解决Get方法的文章. 关于编码的约定,从项目的一开始就要规定 ...
- scrapy RuntimeError: maximum recursion depth exceeded while calling a Python object 超出python最大递归数异常
2019-10-21 19:01:00 [scrapy.core.engine] INFO: Spider opened2019-10-21 19:01:00 [scrapy.extensions.l ...
- 【转】如何使用jupyter编写数学公式(译)
[1.如何使用jupyter编写数学公式(译)][1] [1]: https://www.jianshu.com/p/93ccc63e5a1b
- Spring-Security-Oauth2 基于JDBC存储令牌和RBAC权限认证
相关配置来自李哥博客: https://funtl.com/zh/spring-security-oauth2/ (本文仅记录自己学习过程,说的不详细,可以观看李哥博客) 认证服务器和资源服务器 ...
- 资源管理与调度系统-YARN的资源调度器
资源管理与调度系统-YARN的资源调度器 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 资源调度器是Hadoop YARN中最核心的组件之一,它是ResourceManager中的 ...
- DevExpress GridControl 使用瀑布加载方式加载数据
从事winform开发已经快三年了,这三年中两年使用DevExpress控件进行winform系统开发,对Dev控件有自己的一些思考,下面就常用的表格控件GridControl的分页进行一些讨论. 在 ...
- 51nod 2485 小b重排字符串
小b有一个字符串S,现在她希望重排列S,使得S中相邻字符不同. 请你判断小b是否可能成功. 样例解释:将"aab"重排为"aba"即可. 收起 输入 输入一 ...
- 忘记 MySQL 的 root 帐号密码该怎么办
如果你忘了 MySQL 的 root 帐号密码,别担心,使用下面步骤就可以重设一个新密码: 首先停止 MySQL 服务 “/etc/init.d/mysql stop” 启动 MySQL 服务并屏蔽用 ...