题目链接

【洛谷】

题解

很明显是要用线段树合并的。
对于当前的每一个连通块都建立一个权值线段树。
权值线段树处理操作中的\(k\)大的问题。
如果需要合并,那么就线段树暴力合并,时间复杂度是\(nlogn\),均摊下来就是\(logn\)。
判断联通性的问题就用并查集来解决。
如果在同一个联通块里,就不能合并,否则会出一点问题。

代码

#include <bits/stdc++.h>

using namespace std;

const int N = 3000000 + 6;

int rt[N], id[N], fa[N];
int n, m, v[N], k;
char opt[5];

namespace seg {
int ncnt = 0;
struct node {
    int lc, rc, sz;
    node() { lc = rc = sz = 0; }
} tr[N << 1];
void pushup(int nod) {
    tr[nod].sz = tr[tr[nod].lc].sz + tr[tr[nod].rc].sz;
}
void ins(int &nod, int l, int r, int k) {
    if (!nod) nod = ++ ncnt;
    if (l == r) {
        tr[nod].sz = 1;
        return;
    }
    int mid = (l + r) >> 1;
    if (k <= mid) ins(tr[nod].lc, l, mid, k);
    else ins(tr[nod].rc, mid + 1, r, k);
    pushup(nod);
}
int kth(int x, int l, int r, int rk) {
    if (l == r) return l;
    int mid = (l + r) >> 1;
    if (tr[tr[x].lc].sz >= rk) return kth(tr[x].lc, l, mid, rk);
    else return kth(tr[x].rc, mid + 1, r, rk - tr[tr[x].lc].sz);
}
int merge(int x, int y) {
    if (!x) return y;
    if (!y) return x;
    tr[x].lc = merge(tr[x].lc, tr[y].lc);
    tr[x].rc = merge(tr[x].rc, tr[y].rc);
    pushup(x);
    return x;
} }

int gf(int x) {
    return x == fa[x] ? x : fa[x] = gf(fa[x]);
}
int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i ++) {
        scanf("%d", &v[i]);
        fa[i] = i;
        id[v[i]] = i;
    }
    for (int i = 1, a, b; i <= m; i ++) {
        scanf("%d%d", &a, &b);
        int x = gf(a), y = gf(b);
        fa[x] = y;
    }
    for (int i = 1; i <= n; i ++) seg::ins(rt[gf(i)], 1, n, v[i]);
    scanf("%d", &k);
    while (k --) {
        scanf("%s", opt); int x, y; scanf("%d%d", &x, &y);
        if (opt[0] == 'Q') {
            int z = gf(x);
            if (seg::tr[rt[z]].sz < y) puts("-1");
            else {
                int t = seg::kth(rt[z], 1, n, y);
                printf("%d\n", id[t]);
            }
        } else {
            int a = gf(x), b = gf(y);
            if (a == b) continue;
            fa[a] = b;
            rt[b] = seg::merge(rt[a], rt[b]);
        }
    }
    return 0;
}

「BZOJ2733」「洛谷3224」「HNOI2012」永无乡【线段树合并】的更多相关文章

  1. 【BZOJ2733】【HNOI2012】永无乡 - 线段树合并

    题意: Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通 ...

  2. 洛谷P3224 [HNOI2012]永无乡(线段树合并+并查集)

    题目描述 永无乡包含 nnn 座岛,编号从 111 到 nnn ,每座岛都有自己的独一无二的重要度,按照重要度可以将这 nnn 座岛排名,名次用 111 到 nnn 来表示.某些岛之间由巨大的桥连接, ...

  3. BZOJ2733[HNOI2012]永无乡——线段树合并+并查集+启发式合并

    题目描述 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达 ...

  4. bzoj2733: [HNOI2012]永无乡 线段树合并

    永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以从一个岛 到达另一个岛. ...

  5. 【bzoj2733】[HNOI2012]永无乡 线段树合并

    Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通过桥可以 ...

  6. 洛谷P4770 [NOI2018]你的名字 [后缀自动机,线段树合并]

    传送门 思路 按照套路,直接上后缀自动机. 部分分:\(l=1,r=|S|\) 首先把\(S\)和\(T\)的后缀自动机都建出来. 考虑枚举\(T\)中的右端点\(r\),查询以\(r\)结尾的串最长 ...

  7. 【洛谷3224/BZOJ2733】[HNOI2012]永无乡 (Splay启发式合并)

    题目: 洛谷3224 分析: 这题一看\(n\leq100000\)的范围就知道可以暴力地用\(O(nlogn)\)数据结构乱搞啊-- 每个联通块建一棵Splay树,查询就是Splay查询第k大的模板 ...

  8. 洛谷.3224.[HNOI2012]永无乡(Splay启发式合并)

    题目链接 查找排名为k的数用平衡树 合并时用启发式合并,把size小的树上的所有节点插入到size大的树中,每个节点最多需要O(logn)时间 并查集维护连通关系即可 O(nlogn*insert t ...

  9. 洛谷P4254 [JSOI2008]Blue Mary开公司(李超线段树)

    题面 传送门 题解 李超线段树板子 具体可以看这里 //minamoto #include<bits/stdc++.h> #define R register #define fp(i,a ...

  10. 洛谷P4493 [HAOI2018]字串覆盖(后缀自动机+线段树+倍增)

    题面 传送门 题解 字符串就硬是要和数据结构结合在一起么--\(loj\)上\(rk1\)好像码了\(10k\)的样子-- 我们设\(L=r-l+1\) 首先可以发现对于\(T\)串一定是从左到右,能 ...

随机推荐

  1. 学了两天 react,乱讲一下学习思路,顺便弄了一个脚手架

    之前一直用 vue 做一些小项目,最近接触了一个项目是用 react 做前端,虽然本身是做后端开发的,但是前端还是要了解一点的. 现在的项目基本上都是前后端分离的,后端就先不提了.前端的框架也是层出不 ...

  2. Vb.net MakeLong MAKELPARAM 合并整数代码

    Function MAKELPARAM(wLow As UShort, wHigh As UShort) As UInteger Return wHigh * &H10000 + wLow E ...

  3. 面试常问的几个排序和查找算法,PHP实现

    冒泡,快排,二分查找,都是面试常问的几个算法题目,虽然简单,但是一段时间不用的话就很容易忘记,这里我用PHP实现了一下,温故而知新. 排序 冒泡排序 每一次冒出一个最大的值 function bubb ...

  4. 折腾Java设计模式之状态模式

    原文地址 折腾Java设计模式之状态模式 状态模式 在状态模式(State Pattern)中,类的行为是基于它的状态改变的.这种类型的设计模式属于行为型模式.在状态模式中,我们创建表示各种状态的对象 ...

  5. 20190409-层叠の层叠上下文、层叠水平、层叠顺序、z-index、伪元素层叠

    写在前面乱七八糟的前言: 此"八卦"的源于,在写下图这个圆滚滚的导航布局时,使用元素及其伪元素加上绝对定位完成,但遇到:before或:after伪元素与元素的层叠顺序,就是伪元素 ...

  6. IE中iframe标签显示在DIV之上的问题解决方案

    在做网页时前端时,使用IE打开时会出现标题栏DIV被遮挡PDF遮挡, 后在stackoverflow中查到是IE浏览器的问题:链接https://stackoverflow.com/questions ...

  7. react异步加载组件

    1. 创建 asyncComponent 异步加载工具 import React from 'react' function asyncComponent(loadComponent){ class ...

  8. (办公)git入门

    git版本库(分布式版本控制系统),可以记录每次文件的改动,是程序开发的好帮手. 1.创建版本库: repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文 ...

  9. XMind 8 Pro 破解

    1.补丁下载地址 链接:https://pan.baidu.com/s/146qcwkvOGCAneIXabSZSUA    提取码:wygs 2.安装 XMind 8 Pro, 运行 3. 去除检查 ...

  10. 【夯实shell基础】shell基础面面观

    本文地址 点击关注微信公众号 wenyuqinghuai 分享提纲: 1. shell中的函数 2. shell中的数组 3. shell中的变量 4. shell中的运算符 5. Linux的一些命 ...