UVA1455 – Kingdom(并查集 + 线段树)

UVA1455 – Kingdom(并查集 + 线段树)

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

UVA1455 – Kingdom(并查集 + 线段树)

题目链接

题目大意:一个平面内,给你n个整数点,两种类型的操作:road x y 把city x 和city y连接起来,line fnum (浮点数小数点一定是0.5) 查询y = fnum这条直线穿过了多少个州和city。州指的是连通的城市。

解题思路:用并查集记录城市之间是否连通,还有每一个州的y的上下界。建立坐标y的线段树,然后每次运行road操作的时候,对范围内的y坐标进行更新;更新须要分三种情况:两个州是相离,还是相交,还是包括(这里指的是y坐标的关系);而且由于这里查询是浮点数,所以更新的时候[l,r]的时候,仅仅更新[l,r),这里的r留给它以下的点,这样每次查询的时候就能够查询(int)fnum。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn = 1e6 + 5;
const int N = 1e5 + 5;
#define lson(x) (x<<1)
#define rson(x) ((x<<1) | 1)

struct Node {

    int l, r, ns, nc;
    void set (int l, int r, int ns, int nc) {

        this->l = l;
        this->r = r;
        this->ns = ns;
        this->nc = nc;
    }
}node[4 * maxn];

void pushup (int u) {

    node[u].set (node[lson(u)].l, node[rson(u)].r, 0, 0);
}

void add_node (int u, int adds, int addc) {

    node[u].ns += adds;
    node[u].nc += addc;    
}

void pushdown (int u) {

    if (node[u].ns || node[u].nc) {
        add_node(lson(u), node[u].ns, node[u].nc);
        add_node(rson(u), node[u].ns, node[u].nc);    
    }
}

void build (int u, int l, int r) {

    if (l == r) {
        node[u].set (l, r, 0, 0);
        return;
    }

    int m = (l + r)>>1;
    build (lson(u), l, m);
    build (rson(u), m + 1, r);
    pushup(u);
}

void update (int u, int l, int r, int addc, int adds) {

    if (node[u].l >= l && node[u].r <= r) {
        add_node (u, adds, addc);    
        return;
    }

    int m = (node[u].l + node[u].r)>>1;
    pushdown(u);
    if (l <= m)
        update (lson(u), l, r, addc, adds);
    if (r > m)
        update (rson(u), l, r, addc, adds);
    pushup(u);
}

int query (int u, int x) {

    if (node[u].l == x && node[u].r == x)
        return u;

    int m = (node[u].l + node[u].r)>>1;
    int ans;

    pushdown(u);
    if (x <= m)
        ans = query (lson(u), x);
    else
        ans = query (rson(u), x);
    pushup(u);
    return ans;
}

int p[N], cnt[N], L[N], R[N];
int n, m;

int getParent (int x) {
    return x == p[x] ? x: p[x] = getParent (p[x]);
}

void change (int u, int l, int r, int addc, int adds) {

    if (r < l) //注意
        return;
    update (u, l, r, addc, adds); 
}

void Union(int x, int y) {

    x = getParent (x);
    y = getParent (y);

    if (x == y)
        return;

    if (L[x] >= L[y])
        swap(x, y);

    if (R[x] <= L[y]) {//相离

        change (1, L[x], R[x] - 1, cnt[y], 0);        
        change (1, L[y], R[y] - 1, cnt[x], 0);
        change (1, R[x], L[y] - 1, cnt[x] + cnt[y], 1);
    } else if (R[y] <= R[x]) {//包括

        change (1, L[x], L[y] - 1, cnt[y], 0);
        change (1, R[y], R[x] - 1, cnt[y], 0);
        change (1, L[y], R[y] - 1, 0, -1);
    } else {//相交

        change (1, L[x], L[y] - 1, cnt[y], 0);
        change (1, R[x], R[y] - 1, cnt[x], 0);
        change (1, L[y], R[x] - 1, 0, -1);
    }

    p[x] = y;
    cnt[y] += cnt[x];
    L[y] = min (L[y], L[x]);
    R[y] = max (R[y], R[x]);
}

void init () {

    int x, y;
    scanf ("%d", &n);

    for (int i = 0; i < n; i++) {
        scanf ("%d%d", &x, &y);
        p[i] = i;
        cnt[i] = 1;
        L[i] = R[i] = y;

    }

    scanf ("%d", &m);
    build (1, 0, maxn - 5);
}

void solve () {

    char str[100];
    int x, y;
    double q;

    for (int i = 0; i < m; i++) {

        scanf ("%s", str);

        if (str[0] == 'r') {
            scanf ("%d%d", &x, &y);        
            Union(x, y);
        } else {
            scanf ("%lf", &q);
            x = query (1, (int)q);
            printf ("%d %d\n", node[x].ns, node[x].nc);
        }
    }
}

int main () {

    int T;
    scanf ("%d", &T);

    while (T--) {

        init();
        solve();    
    }
    return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/118052.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • BatchNorm 理解

    BatchNorm 理解BN可以说是NN发展中的一个里程碑式的结构了,不增加inference时间,调参变得简单,收敛更快效果更好。虽然提出的时间已经很久了,而且网上关于BN的解释一堆一堆的,但是博主觉得有不少解释是欠妥的,在此贴出博主贴出对caffe中BN源码的解释和自己对BN的理解,欢迎讨论。caffe中BN的实现比较反人类。BatchNorm层单纯实现标准化,再用一个scale层添加  参数,共同完成BN。…

    2022年5月22日
  • ubuntu下安装pycharm教程_可以在开始菜单中创建快捷方式吗

    ubuntu下安装pycharm教程_可以在开始菜单中创建快捷方式吗在Ubuntu18中安装Pycharm及创建Pycharm快捷方式一、在Ubuntu18.04中安装Pycharm1.到PyCharm网站下载pycharmprofessional2018.2.4版本:https://www.jetbrains.com/pycharm/点击DOWNLOADNOW按钮,进入系统版本下载页面图片1图片2点击专业版下载2.将下载的这个安装包解…

    2022年8月28日
  • phpstorm PhpStorm 2021.3.20 激活码 3月最新注册码

    phpstorm PhpStorm 2021.3.20 激活码 3月最新注册码,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月15日
  • idea中选中一行的快捷键_idea撤销快捷键恢复

    idea中选中一行的快捷键_idea撤销快捷键恢复之前前端开发一直使用VSCode,常用快捷键删除一行或者当前选中的几行代码,使用idea的时候发现快捷键并不相同,查看发现idea的快捷是:Ctrl+Y,比手动删除代码方便很多。通过File->Setttings->Keymap可以查看已经设置好的快捷键:…

    2022年9月7日
  • 猴子吃香蕉编程题_2只小猴子摘了3根香蕉

    猴子吃香蕉编程题_2只小猴子摘了3根香蕉实验目的(1)熟悉谓词逻辑表示法;(2)掌握人工智能谓词逻辑中的经典例子——猴子摘香蕉问题的编程实现。实验内容房子里有一只猴子(即机器人),位于a处。c处上方的天花板上有一串香蕉,猴子想吃,但摘不到。房间的b处还有一个箱子,如果猴子站到箱子上,就可以摸着天花板。如图所示,对于上述问题,可以通过谓词逻辑表示法来描述知识。要求通过python语言编程实现猴子摘香蕉问题的求解过程。”’猴子摘香蕉问题的Python编程实现”’#全局变量ii=0defMonkey_go_box(x,y.

    2022年9月26日
  • 2021 pycharm 激活码_通用破解码

    2021 pycharm 激活码_通用破解码,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月16日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号