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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Centos7部署Nginx负载均衡Tomcat服务器及session共享架构

    Centos7部署Nginx负载均衡Tomcat服务器及session共享架构

    2022年2月15日
    43
  • pycharm及python安装详细教程_python基础教程

    pycharm及python安装详细教程_python基础教程python下载安装图文教程-Pycharm下载安装图文教程Python及Pycharm安装图文教程,供大家参考,具体内容如下为了学习Python我今天对它进行了安装,并将Python及Pycharm安装方法进行了分享,希望可以帮助到大家注:建议大家在安装过程中不要将软件安装到系统盘中。1、Python安装1)首先需要进入Python官网下载安装包,进入后点击Downloads找到如下界面:可以根据自己的系统下载适合的安装包下载完成后直接…

    2022年8月27日
    2
  • 查看mysql慢日志_docker查看实时日志的命令

    查看mysql慢日志_docker查看实时日志的命令慢查询日志是否开启showvariableslike’%slow_query_log%’;#如果结果中包含slow_query_log|OFF,则说明慢日志已经关闭#开启慢查询日志的方式:setglobalslow_query_log=1;慢查询sql的设置时间查看慢查询sql的设置时间,默认10s,sql执行时间大于该时间的才是慢sql,才会记录到慢查询…

    2022年10月12日
    0
  • sql服务器系统时间格式,SQL Server 日期格式和日期操做

    sql服务器系统时间格式,SQL Server 日期格式和日期操做SQLServer发展至今,关于日期的格式的控制方法,有传统的方法,好比CONVERT(),也有比较便利的新方法,好比FORMAT();一样,关于日期的操做函数,也分为传统方法:DATEADD()等,也有便利的新方法:EOMonth()等。sql一,日期的格式化格式化是指把日期类型(Date)、日期和时间类型转化为字符类型,一般使用CONVERT()和FORMAT()函数。express1,传统…

    2022年10月19日
    1
  • Java常用的输入输出语句「建议收藏」

    Java常用的输入输出语句「建议收藏」对于经常上机刷题的来说,首先得解决输入输出方法,Java的输入输出流在Java学习过程的后面部分才会接触,但是我们可以掌握一些简单的,常用的输入输出方法首先输出大家最熟悉的莫过于输出方法,直接用System.out.println()或者System.out.print()了下面一个实例1234567publicclassMain{    publicstaticvoidmain(Str…

    2022年5月26日
    56
  • 动态链接库(DLL)初始化例程失败_load dll error解决

    动态链接库(DLL)初始化例程失败_load dll error解决UnabletoloadDLL’rasapi32.dll’:动态链接库(DLL)初始化例程失败。(ExceptionfromHRESULT:0x8007045A)解决方法:应用程序池-标识-选本地系统或者输入管理员身份的账户

    2022年10月9日
    0

发表回复

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

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