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)
上一篇 2021年12月14日 下午12:00
下一篇 2021年12月14日 下午12:00


相关推荐

  • java实现coze平台鉴权+工作流调用(踩坑记录)

    java实现coze平台鉴权+工作流调用(踩坑记录)

    2026年3月12日
    2
  • 怎么理解泊松分布_泊松分布公式

    怎么理解泊松分布_泊松分布公式1甜在心馒头店公司楼下有家馒头店:每天早上六点到十点营业,生意挺好,就是发愁一个事情,应该准备多少个馒头才能既不浪费又能充分供应?老板统计了一周每日卖出的馒头(为了方便计算和讲解,缩小了数据):均值为:按道理讲均值是不错的选择(参见如何理解最小二乘法?),但是如果每天准备5个馒头的话,从统计表来看,至少有两天不够卖,的时间不够卖:你“甜在心馒头店”又不是…

    2022年8月30日
    4
  • Hystrix服务熔断

    Hystrix服务熔断1 简介 1 1 什么是 Hystrix 1 2 服务雪崩 2 线程隔离 amp 服务降级 2 1 原理 2 2 案例 1 引入依赖 2 开启熔断 3 编写降级逻辑 4 默认的 fallback5 超时设置 3 服务熔断 3 1 熔断原理 3 2 案例 1 简介 1 1 什么是 Hystrix Hystrix 是一个应用于处理分布式系统的延迟和容错的开源库 在分布式系统里 许多依赖不可避免的会调用失败 比如超时 异常等 Hystrix 能够保证在一个依赖出问题的情况下 不会导致整个体系服务失败 避免级联故障 以提高分布式系

    2026年3月26日
    3
  • 公司测试环境k8s节点故障解决

    公司测试环境k8s节点故障解决

    2021年5月29日
    157
  • 三月估值翻四倍,Kimi改写AI叙事?

    三月估值翻四倍,Kimi改写AI叙事?

    2026年3月16日
    2
  • java电驴_java写的电驴下载完成关机小程序

    java电驴_java写的电驴下载完成关机小程序经常用到电驴下载资料 一些 http 你根本找不到的资源 当然速度是不能恭维了 驴子么 干的就是慢活 热门资源除外 我用的 verycd 版的电驴 原版电驴的一种 mods 电驴貌似有 N 多版本 不过我觉得 verycd 的就够用了 毕竟国内八成的人都在用 最近在下新东方的新概念英语教程 进度 87 眼看要下完了 等要等 1 个多小时 下载完成又不自动关机 很是苦恼 虽然 verycd 一直提倡共享互联网 下载完成关机也

    2026年3月18日
    4

发表回复

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

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