[bzoj2733]永无乡&&[bzoj3545]Peaks
并不敢说完全会了线段树合并,只是至少知道原理写法了。。。还是太菜了,每天被大佬吊锤qwq
我看到的几道线段树合并都是权值线段树的合并。这个算法适用范围应该只是01线段树的。
这两道算入门题了吧。。。
发现粘题面没人看(自己都懒得看),以后粘链接加题意吧。
给$n$个没有连边的带权点,动态加边,询问$u$所在连通块权值第$k$大的点是什么。$n \leq 1e5 , q\leq 3e5$
给定森林,点有点权有重复!,边有边权。询问$u$所在连通块,只能走边权小于$w$的边,可达的权值第$k$大的点编号!是什么。$n \leq 1e5 , m,q \leq 5e5$ 被坑的巨惨qwq
后面的离线一下,按边权从小到大加进去就和永无乡一样了。
并查集维护连通性,并将两个连通块的权值线段树合并。询问就是在所在连通块线段树二分找。$(O(nlogn))$
#include<bits/stdc++.h>
using namespace std;
const int N=;
inline int read(){
int r=,c=getchar();
while(!isdigit(c))c=getchar();
while(isdigit(c))
r=r*+c-'',c=getchar();
return r;
}
int fa[N],rt[N],n,m;
int find(int x){
return x==fa[x]?x:fa[x]=find(fa[x]);
}
struct Node{
int L,R,sum;
}T[N*];
int sz;
#define ls T[o].L
#define rs T[o].R
void pullup(int o){
T[o].sum=T[ls].sum+T[rs].sum;
}
void ins(int &o,int l,int r,int v){
if(!o)o=++sz;
if(l==r){
T[o].sum=;return;
}
int mid=l+r>>;
if(v<=mid)ins(ls,l,mid,v);
else ins(rs,mid+,r,v);
pullup(o);
}
int merge(int x,int y){
if(!x)return y;
if(!y)return x;
T[x].L=merge(T[x].L,T[y].L);
T[x].R=merge(T[x].R,T[y].R);
pullup(x);
return x;
}
int query(int o,int l,int r,int rk){
if(l==r)return l;
int mid=l+r>>;
if(rk<=T[ls].sum)return query(ls,l,mid,rk);
else return query(rs,mid+,r,rk-T[ls].sum);
}
void Link(int x,int y){
int u=find(x),v=find(y);
fa[u]=v;rt[v]=merge(rt[u],rt[v]);
}
int a[N],id[N];
void init(){
n=read(),m=read();
for(int i=;i<=n;i++)
a[i]=read(),id[a[i]]=fa[i]=i;
while(m--){
int u=read(),v=read();
fa[find(u)]=find(v);
}
for(int i=;i<=n;i++)
ins(rt[find(i)],,n,a[i]);
}
void solve(){
m=read();
char s[];
while(m--){
scanf("%s",s);
if(s[]=='B'){
int u=read(),v=read();
Link(u,v);
}
else{
int u=find(read()),rk=read();
if(T[rt[u]].sum<rk)puts("-1");
else printf("%d\n",id[query(rt[u],,n,rk)]);
}
}
}
int main(){
init();
solve();
}
2733
#include<bits/stdc++.h>
using namespace std;
const int N=;
const int M=;
inline int read(){
int r=,c=getchar();
while(!isdigit(c))c=getchar();
while(isdigit(c))
r=r*+c-'',c=getchar();
return r;
}
int n,m,q;
struct Edge{
int u,v,w;
friend bool operator < (Edge p,Edge q){
return p.w<q.w;
}
}e[M];
struct ask{
int u,w,k,ans,id;
}a[M];
bool cmpw(ask p,ask q){
return p.w<q.w;
}
bool cmpid(ask p,ask q){
return p.id<q.id;
}
int fa[N],h[N],t[N],id[N];
inline int find(int x){
return x==fa[x]?x:fa[x]=find(fa[x]);
}
int rt[N],sz;
struct Node{
int L,R,sum;
}T[N*];
#define ls T[o].L
#define rs T[o].R
#define mid (l+r>>1)
inline void pullup(int o){
T[o].sum=T[ls].sum+T[rs].sum;
}
void ins(int &o,int l,int r,int val){
if(!o)o=++sz;
if(l==r){
T[o].sum=;return;
}
if(val<=mid)ins(ls,l,mid,val);
else ins(rs,mid+,r,val);
pullup(o);
}
int query(int o,int l,int r,int rk){
if(l==r){
return t[l];
}
if(rk<=T[ls].sum)return query(ls,l,mid,rk);
else return query(rs,mid+,r,rk-T[ls].sum);
}
int merge(int x,int y){
if(!x)return y;
if(!y)return x;
if(!T[x].L&&!T[x].R){
T[x].sum+=T[y].sum;
return x;
}
T[x].L=merge(T[x].L,T[y].L);
T[x].R=merge(T[x].R,T[y].R);
pullup(x);return x;
}
inline void Link(int x,int y){
x=find(x),y=find(y);
if(x==y)return;
fa[y]=x;
rt[x]=merge(rt[x],rt[y]);
}
void init(){
n=read(),m=read(),q=read();
for(int i=;i<=n;i++)
h[i]=t[i]=read(),fa[i]=i;
sort(t+,t+n+);
for(int i=;i<=n;i++){
h[i]=lower_bound(t+,t+n+,h[i])-t;
ins(rt[i],,n,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++)
a[i].u=read(),a[i].w=read(),a[i].k=read(),a[i].id=i;
sort(a+,a+q+,cmpw);
}
void solve(){
int now=;
for(int i=;i<=q;i++){
int lim=a[i].w,rk=a[i].k;
while(e[now].w<=lim&&now<=m){
Link(e[now].u,e[now].v);now++;
}
int u=find(a[i].u),siz=T[rt[u]].sum;
if(siz<rk){
a[i].ans=-;continue;
}
else rk=siz-rk+;
a[i].ans=query(rt[u],,n,rk);
}
sort(a+,a+q+,cmpid);
for(int i=;i<=q;i++)
printf("%d\n",a[i].ans);
}
int main(){
init();
solve();
}
3545
[bzoj2733]永无乡&&[bzoj3545]Peaks的更多相关文章
- BZOJ2733 永无乡【splay启发式合并】
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- BZOJ2733 永无乡 【splay启发式合并】
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 4190 Solved: 2226 [Submit][Sta ...
- [BZOJ2733]永无乡
Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以 ...
- bzoj2733永无乡
永无乡 HYSBZ - 2733 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接, ...
- bzoj2733 永无乡 splay树的启发式合并
https://vjudge.net/problem/HYSBZ-2733 给一些带权点,有些点是互相连通的, 然后给出2种操作,在两点间加一条边,或者询问一个点所在的连通块内的第k小值的编号 并查集 ...
- 【BZOJ2733】永无乡(线段树,并查集)
[BZOJ2733]永无乡(线段树,并查集) 题面 BZOJ 题解 线段树合并 线段树合并是一个很有趣的姿势 前置技能:动态开点线段树 具体实现:每次合并两棵线段树的时候,假设叫做\(t1,t2\), ...
- [bzoj2733][HNOI2012]永无乡_权值线段树_线段树合并
永无乡 bzoj-2733 HNOI-2012 题目大意:题目链接. 注释:略. 想法: 它的查询操作非常友善,就是一个联通块内的$k$小值. 故此我们可以考虑每个联通块建一棵权值线段树. 这样的话每 ...
- 【题解】永无乡 [HNOI2012] [BZOJ2733] [P3224]
[题解]永无乡 [HNOI2012] [BZOJ2733] [P3224] [题目描述] 永无乡包含 \(n\) 座岛,编号从 \(1\) 到 \(n\) ,每座岛都有自己的独一无二的重要度,按照重要 ...
- 【BZOJ-2733】永无乡 Splay+启发式合并
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2048 Solved: 1078[Submit][Statu ...
随机推荐
- JavaScript 常用的Math对象
Math.ceil(x); //返回x向上取整后的整数值. Math.floor(x); //返回x向下取整后的整数值.. Math.round(x); //返回四舍五入后的整数. Math.abs( ...
- 整理齐全 - Vultr VPS自定义安装Windows ISO(2003/2012/2008/WIN7)
最近公司有几个项目是需要在Windows VPS服务器中运行调试的,但是公司给予的成本有限,所以只能在Linux VPS中考虑,毕竟Linux服务器相比Windows系统便宜很多.开始我们运维部门考虑 ...
- JS回调函数(理解篇)
概述: 回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数.回调函数不是由该函数的实现方直接调用,而 ...
- 【CCPC-Wannafly Winter Camp Day4 (Div1) I】咆咆咆哮(三分+贪心)
点此看题面 大致题意: 有\(n\)张卡牌,每张卡牌有两种用法:使场上增加一个伤害为\(a_i\)的生物,或使场上所有生物伤害增加\(b_i\).求最大总伤害. 三分 我们可以三分使用\(a_i\)的 ...
- 转:adb操作命令详解及大全
说到 ADB 大家应该都不陌生,即 Android Debug Bridge,Android调试桥,身为 Android 开发的我们,熟练使用 ADB 命令将会大大提升我们的开发效率, ADB 的命令 ...
- P1424 小鱼的航程(改进版)
题目背景 原来的题目太简单,现改进让小鱼周末也休息,请已经做过重做该题. 题目描述 有一只小鱼,它上午游泳150公里,下午游泳100公里,晚上和周末都休息(实行双休日),假设从周x(1<=x&l ...
- arraylist,list ,数组区别
https://www.cnblogs.com/a164266729/p/4561651.html
- fluent Python
1.1 Python风格的纸牌 Python collections模块中的内置模块:namedtuple https://www.liaoxuefeng.com/wiki/0013747381250 ...
- CPP-STL:用vector保存对象时保存指针的优点, 以及reserve的使用(转)
代码1 #include <vector> #include <stdio.h> class A { public: A() { printf("A()/n" ...
- background-position设置
设置背景图片的位置:background-position:x y; 其中x和y可以为百分比也可以为像素