洛谷P3224 永无乡 - 连通块合并查询第k小权值 并查集+线段树合并

题目链接:https://www.luogu.com.cn/problem/P3224
题目大意:


思路:直接给每个岛建立一棵线段树。然后用并查集合并岛,线段树合并一下两个岛的权值。
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int N = 1e5+5;

int w[N], p[N], lc[N*20], rc[N*20], rt[N*20], id[N*20], tot=0, n, m;
vector<int> v[N];
int tre[N*20], ans[N];//节点信息

void Insert(int &i, int l, int r, int x, int Id){//建树
    if(r<l) return;
    i=++tot;//点
    if(l==r){
        id[i]=Id;
        tre[i]++; return ;
    }
    int mid=(l+r)>>1;
    if(x<=mid) Insert(lc[i], l, mid, x, Id);
    if(x>mid) Insert(rc[i], mid+1, r, x, Id);
    tre[i]=tre[lc[i]]+tre[rc[i]];//权值在区间[l, r]的元素个数
}

int Merge(int x, int y){//合并
    if(!x) return y;
    if(!y) return x;
    lc[x]=Merge(lc[x], lc[y]);
    rc[x]=Merge(rc[x], rc[y]);
    tre[x]=tre[lc[x]]+tre[rc[x]];//节点信息合并

    return x;
}

int query(int root, int l, int r, int x){//查询子树中权值<=x的节点个数
    if(!root) return -1;
    if(!x) return -1;
    if(l==r){
        if(tre[root]>=x){
            return id[root];
        }
        return -1;
    }
    int mid=(l+r)>>1;
    if(x>tre[lc[root]]) return query(rc[root], mid+1, r, x-tre[lc[root]]);
    else  return query(lc[root], l, mid, x);
}

int f[N];
int fd(int x){
    if(f[x]==x) return x;
    return f[x]=fd(f[x]);
}
int main(){

    int x, y, q;
    scanf("%d%d", &n, &m);
    for(int i=1; i<=n; i++){
        scanf("%d", &w[i]);
        f[i]=i;
    }
    for(int i=1; i<=n; i++){
        Insert(rt[i], 1, n, w[i], i);
    }
    for(int i=1; i<=m; i++){
        scanf("%d%d", &x, &y);
        x=fd(x), y=fd(y); f[y]=x;
        rt[x]=Merge(rt[x], rt[y]);

    }
    scanf("%d", &q);
    while(q--){
        char op[5];
        scanf("%s%d%d", op, &x, &y);
        x=fd(x);
        if(op[0]=='B'){
            y=fd(y);
            if(x==y) continue;
            f[y]=x;
            rt[x]=Merge(rt[x], rt[y]);
            //cout<<rt[x]<<" : "<<tre[rt[x]]<<endl;
        }
        else{
            printf("%d\n", query(rt[x], 1, n, y));
        }
    }

    return 0;

}




全部评论

相关推荐

03-27 16:40
已编辑
门头沟学院 C++
26学院本太难了,很多公司机筛就给我刷了。机会都难拿到如果是简历存在问题也欢迎拷打————————————————————分割线——————————————————————2026.3.4更新:发完贴之后,时不时投递又收到了不少的笔试/面试邀请。主要是之前投递简历出去之后基本上都是沉默状态,年后好转了不少timeline:2026.01.21&nbsp;文远知行笔试,半年多没刷算法题&nbsp;-&gt;挂&nbsp;(后续HR说春招可以重新安排笔试)2026.2.4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;小鹏汇天&nbsp;技术一面,第二周收到结果&nbsp;-&gt;挂2026.2.12&nbsp;&nbsp;&nbsp;大众Cariad代招&nbsp;技术二面&nbsp;-&gt;Offer2026.2.28&nbsp;&nbsp;&nbsp;多益网络技术面试,由于风评太差,一直在犹豫要不要接面试&nbsp;-&gt;推迟-----------分割线-----------2026.3&nbsp;月前的某一天,临时去电网报名了二批计算机岗位的笔试2026.3.6&nbsp;从上家公司实习离职,氛围最好的一家公司,leader&nbsp;说可以帮忙转正,但是流程太长,而且我们部门据说只有一个&nbsp;hc,更想要研究生,我很有可能是会被签外包公司在这里干活,就离职了。2026.3.9&nbsp;入职新公司,大众Cariad&nbsp;以外部公司的身份进组,项目组签了三年,后续三年应该都可以在这里呆,不知道有没有希望原地跳槽。2026.3.10&nbsp;电网考试居然说我通过资格审查了,短信约我去参加资格审查,请假一天,买了&nbsp;12&nbsp;号晚上的机票回成都2026.3.15&nbsp;参加国家电网计算机类笔试2026.3.17&nbsp;电网出成绩了,感觉很低。觉得已经🈚️了2026.3.18&nbsp;收到电网面试通知,通知&nbsp;3.22-3.25&nbsp;这个时间去面试,我的岗位只招&nbsp;1&nbsp;个人。据说面试只有&nbsp;2-3&nbsp;人,不知道能不能成功----------分割线-----------2026.3.21&nbsp;电网面试结束,感觉回答的还勉勉强强,大概是2个岗位分别招1个人,一共11人面试,实际来了9人2026.3.27&nbsp;出面试成绩,满分100分,早上10:20左右发现面试成绩46,我震惊了,没截图,后面过了十分钟重新看发现面试成绩给我改成58了。但同样震惊。朋友问我是不是把面试官打了,哈哈
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
正在热议
更多
# 一张图晒出你司的标语 #
4249次浏览 75人参与
# AI面会问哪些问题? #
27474次浏览 550人参与
# 米连集团26产品管培生项目 #
13285次浏览 285人参与
# 你的实习产出是真实的还是包装的? #
20012次浏览 342人参与
# 找AI工作可以去哪些公司? #
8924次浏览 230人参与
# 春招至今,你的战绩如何? #
64347次浏览 575人参与
# 开放七大实习专项,百度暑期实习值得冲吗 #
15051次浏览 221人参与
# 从事AI岗需要掌握哪些技术栈? #
8776次浏览 299人参与
# 你做过最难的笔试是哪家公司 #
33017次浏览 229人参与
# 中国电信笔试 #
31886次浏览 292人参与
# 投递几十家公司,到现在0offer,大家都一样吗 #
340689次浏览 2173人参与
# 阿里笔试 #
178341次浏览 1314人参与
# 第一份工作一定要去大厂吗 #
14380次浏览 122人参与
# 金三银四,你的春招进行到哪个阶段了? #
22046次浏览 280人参与
# 沪漂/北漂你觉得哪个更苦? #
9741次浏览 193人参与
# HR最不可信的一句话是__ #
6145次浏览 113人参与
# 应届生第一份工资要多少合适 #
20663次浏览 86人参与
# AI时代,哪个岗位还有“活路” #
11407次浏览 339人参与
# 春招你拿到offer了吗 #
831056次浏览 9986人参与
# 长得好看会提高面试通过率吗? #
22510次浏览 254人参与
# 聊聊你的职场新体验 #
336426次浏览 1895人参与
# 学历对求职的影响 #
665090次浏览 4249人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务