题意:

平面上有\(n\)个点,有一种操作和一种查询:

  • \(road \, A \, B\):在\(a\),\(b\)两点之间加一条边
  • \(line C\):询问直线\(y=C\)经过的连通分量的个数以及这些连通分量点的总数

分析:

其实横坐标是没用的,首先可以先将纵坐标离散化。

用并查集维护点的连通性,连通分量的大小以及连通分量中纵坐标的最大值和最小值。

线段树中维护的是每条直线穿过的连通分量的个数以及点的个数之和。

当两个连通分量合并时,先把两个小连通分量从线段树中删去,然后再把合并之后的大连通分量加进去。

修改是区间修改,查询是单点查询。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = 100000 + 10;
const int maxnode = maxn * 4; int n;
int a[maxn], tot, b[maxn]; int pa[maxn], sz[maxn], miny[maxn], maxy[maxn];
int findset(int x) { return x == pa[x] ? x : pa[x] = findset(pa[x]); } int states[maxnode], cities[maxnode]; char cmd[15]; void pushdown(int o, int* add) {
if(add[o] != 0) {
add[o<<1] += add[o];
add[o<<1|1] += add[o];
add[o] = 0;
}
} void pushdown(int o) {
pushdown(o, states);
pushdown(o, cities);
} void update(int o, int L, int R, int qL, int qR, int v1, int v2) {
if(qL <= L && R <= qR) {
states[o] += v1;
cities[o] += v2;
return;
}
pushdown(o);
int M = (L + R) / 2;
if(qL <= M) update(o<<1, L, M, qL, qR, v1, v2);
if(qR > M) update(o<<1|1, M+1, R, qL, qR, v1, v2);
} void query(int o, int L, int R, int pos) {
if(L == R) {
printf("%d %d\n", states[o], cities[o]);
return;
}
pushdown(o);
int M = (L + R) / 2;
if(pos <= M) query(o<<1, L, M, pos);
else query(o<<1|1, M+1, R, pos);
} int main()
{
int T; scanf("%d", &T);
while(T--) {
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
pa[i] = i; sz[i] = 1;
int x; scanf("%d%d", &x, a + i);
b[i - 1] = a[i];
}
sort(b, b + n);
tot = unique(b, b + n) - b;
for(int i = 1; i <= n; i++) {
a[i] = lower_bound(b, b + tot, a[i]) - b;
miny[i] = maxy[i] = a[i];
} memset(states, 0, sizeof(states));
memset(cities, 0, sizeof(cities));
int m; scanf("%d", &m);
while(m--) {
scanf("%s", cmd);
if(cmd[0] == 'r') {
int a, b; scanf("%d%d", &a, &b);
a++; b++;
int fa = findset(a), fb = findset(b);
if(fa == fb) continue;
int L = miny[fa], R = maxy[fa];
if(L < R) update(1, 1, n, L + 1, R, -1, -sz[fa]);
L = miny[fb], R = maxy[fb];
if(L < R) update(1, 1, n, L + 1, R, -1, -sz[fb]);
//Union
pa[fb] = fa;
sz[fa] += sz[fb];
miny[fa] = min(miny[fa], miny[fb]);
maxy[fa] = max(maxy[fa], maxy[fb]);
L = miny[fa], R = maxy[fa];
if(L < R) update(1, 1, n, L + 1, R, 1, sz[fa]);
} else {
double ty; scanf("%lf", &ty);
int y = (int)ty + 1;
y = lower_bound(b, b + tot, y) - b;
query(1, 1, n, y);
}
}
} return 0;
}

UVa 1455 Kingdom 线段树 并查集的更多相关文章

  1. [WC2005]双面棋盘(线段树+并查集)

    线段树+并查集维护连通性. 好像 \(700ms\) 的时限把我的常数超级大的做法卡掉了, 必须要开 \(O_2\) 才行. 对于线段树的每一个结点都开左边的并查集,右边的并查集,然后合并. \(Co ...

  2. 2022.02.27 CF811E Vladik and Entertaining Flags(线段树+并查集)

    2022.02.27 CF811E Vladik and Entertaining Flags(线段树+并查集) https://www.luogu.com.cn/problem/CF811E Ste ...

  3. 【CF687D】Dividing Kingdom II 线段树+并查集

    [CF687D]Dividing Kingdom II 题意:给你一张n个点m条边的无向图,边有边权$w_i$.有q个询问,每次给出l r,问你:如果只保留编号在[l,r]中的边,你需要将所有点分成两 ...

  4. 【BZOJ-3673&3674】可持久化并查集 可持久化线段树 + 并查集

    3673: 可持久化并查集 by zky Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 1878  Solved: 846[Submit][Status ...

  5. 【XSY2707】snow 线段树 并查集

    题目描述 有\(n\)个人和一条长度为\(t\)的线段,每个人还有一个工作范围(是一个区间).最开始整条线段都是白的.定义每个人的工作长度是这个人的工作范围中白色部分的长度(会随着线段改变而改变).每 ...

  6. bzoj 2054: 疯狂的馒头(线段树||并查集)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2054 线段树写法: 点的颜色只取决于最后一次染的颜色,所以我们可以倒着维护,如果当前区间之前 ...

  7. 【BZOJ1453】[Wc]Dface双面棋盘 线段树+并查集

    [BZOJ1453][Wc]Dface双面棋盘 Description Input Output Sample Input Sample Output HINT 题解:话说看到题的第一反应其实是LCT ...

  8. codeforces 811E Vladik and Entertaining Flags(线段树+并查集)

    codeforces 811E Vladik and Entertaining Flags 题面 \(n*m(1<=n<=10, 1<=m<=1e5)\)的棋盘,每个格子有一个 ...

  9. 【Codeforces811E】Vladik and Entertaining Flags [线段树][并查集]

    Vladik and Entertaining Flags Time Limit: 20 Sec  Memory Limit: 512 MB Description n * m的矩形,每个格子上有一个 ...

随机推荐

  1. Swift基础学习笔记

    1.在学基本语法之前,简单看一下与OC的不同 注释:OC       #pragma marks  视图加载完成 Swift    //MARK: 视图加载完成   //TOOO:设置背景颜色(Xco ...

  2. 解决在eclipse中导入项目名称已存在的有关问题

    新建项目-Import-File System-找到相应的文件夹-Overwrite existing resources without warning打钩,选中项目即可

  3. Django--对表的操作

    一丶多表创建 1.创建模型 实例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之 ...

  4. HTML5&CSS挑战

    地址:https://www.w3cschool.cn/codecamp/list?pename=html5_and_css_camp 开始学习HTML标签:欢迎来到编程训练营的第一个编程挑战!你可以 ...

  5. 【MFC】0xC0000005: 读取位置 0x00000020 时发生访问冲突

    原因:使用GetDlgItem()函数时需要先判断指针然后才可以使用. 错误代码: //重新建一个线程,查询帧同步 DWORD WINAPI SCsync_Thread(LPVOID Lparam) ...

  6. 渐变色在IE9以下包括IE9的使用

    因为是不支持gradient的.所以需要使用如下属性,该属性不适用于safria浏览器,并且,#fff不可以简写,要写成#ffffff这样的形式 FILTER: progid:DXImageTrans ...

  7. theano支持的数组、向量、矩阵表达式

    1)theano主要支持符号矩阵表达式 (2)theano与numpy中都有broadcasting:numpy中是动态的,而theano需要在这之前就知道是哪维需要被广播.针对不同类型的数据给出如下 ...

  8. pandas 常用统计方法

    统计方法 pandas 对象有一些统计方法.它们大部分都属于约简和汇总统计,用于从 Series 中提取单个值,或从 DataFrame 的行或列中提取一个 Series. 比如 DataFrame. ...

  9. JS中进行浮点数计算式,遇到的问题

    今天在做项目时,需要在页面进行计算,但是当两个数都是小数时,计算的结果却不是想象中的: 比如1371.3-0.9算出来却是1370.39999999,后来上网搜一下,原来js是弱类型语言,没有那么高的 ...

  10. Access数据库远程连接的实用方法

    一般在远程文件夹开启文件共享即可通过像平常一样用连接字符串访问,注意共享的读写权限. 远程(如通过互联网)连接access数据库的示例: 首先,需要使用TCP/IP,ADO及XML(需要安装Micro ...