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;
}
UVA1455 - Kingdom(并查集 + 线段树)的更多相关文章
- 并查集&线段树&树状数组&排序二叉树
超级无敌巨牛逼并查集(带权并查集)https://vjudge.net/problem/UVALive-4487 带删点的加权并查集 https://vjudge.net/problem/UVA-11 ...
- 【Codeforces576E_CF576E】Painting Edges(可撤销并查集+线段树分治)
题目 CF576E 分析: 从前天早上肝到明天早上qwq其实颓了一上午MC ,自己瞎yy然后1A,写篇博客庆祝一下. 首先做这题之前推荐一道很相似的题:[BZOJ4025]二分图(可撤销并查集+线段树 ...
- BZOJ 3910 并查集+线段树合并
思路: 1. 并查集+线段树合并 记得f[LCA]==LCA的时候 f[LCA]=fa[LCA] 2.LCT(并不会写啊...) //By SiriusRen #include <cstdio& ...
- 并查集 + 线段树 LA 4730 Kingdom
题目传送门 题意:训练指南P248 分析:第一个操作可以用并查集实现,保存某集合的最小高度和最大高度以及城市个数.运用线段树成端更新来统计一个区间高度的个数,此时高度需要离散化.这题两种数据结构一起使 ...
- uvalive 4730王国kingdom(并查集+线段树)
题意:有T组測试数据.每组数据的N表示有N个城市,接下来的N行里每行给出每一个城市的坐标(0<=x,y<=1000000),然后有M(1<M<200000)个操作,操作有 ...
- YYHS-猜数字(并查集/线段树维护)
题目描述 LYK在玩猜数字游戏. 总共有n个互不相同的正整数,LYK每次猜一段区间的最小值.形如[li,ri]这段区间的数字的最小值一定等于xi. 我们总能构造出一种方案使得LY ...
- luogu5012 水の数列 (并查集+线段树)
如果我们能求出来每个区间个数的最大分值,那就可以用线段树维护这个东西 然后出答案了 然后这个的求法和(luogu4269)Snow Boots G非常类似,就是我们把数大小排个序,每次都拿<=x ...
- 【CF471E】MUH and Lots and Lots of Segments 扫描线+并查集+线段树+set
[CF471E]MUH and Lots and Lots of Segments 题意:给你平面上n条水平或竖直的,端点在整点处的线段.你需要去掉一些线段的一些部分,使得剩下的图形:1.连通,2.无 ...
- bzoj 3237 连通图 - 并查集 - 线段树
Input Output Sample Input 4 5 1 2 2 3 3 4 4 1 2 4 3 1 5 2 2 3 2 1 2 Sample Output Connected Disconne ...
随机推荐
- asp.net2.0安全性(1)--用户角色篇(类)--转载来自车老师
Membership.MembershipUser和Roles类 用户与角色管理在asp.net2.0中是通过Membership和Roles两个类来实现的. Membership:用户成员账号管理, ...
- PHPCMS V9数据库配置文件database.php位置
初次用PHPCMS V9的朋友可能找不到数据库配置文件,其实在官方的wiki中已经介绍了.那就是 caches\configs\database.php 文件. 初次用PHPCMS V9的朋友可能找不 ...
- JavaScript编程:javaScript核心基础语法
1.javaScript核心基础语法: javaScript技术体系包含了5个内容: 1.核心语言定义: 2.原生对象和雷子对象: 3.浏览器对象 ...
- org.apache.hadoop.ipc.Client: Retrying connect to server异常的解决
检查发现是DataNode一直连接不到NameNode. 检查各个节点在etc/hosts中的配置是否有127.0.1.1 xxxxxx.如果有把其屏蔽或者删除,重启各节点即可. 原因:127.0.1 ...
- Servlet的学习之Request请求对象(1)
在本篇中开始对Servlet中的HttpServletRequest请求对象进行学习,请求对象同响应对象一样,我们可以根据该对象中的方法获取例如请求行,请求头和请求实体数据的方法. 在本篇中先对Htt ...
- sql为数字添加千分位(也就是钱的格式)
感觉这个东西在项目中用得挺多的,之前在前台页面是用正则来处理,现在由于是数据查询,所以直接在查出数据的时候将其转为指定的千分位格式,省的前台再处理,不讲原理,因为我也看不懂,不过会用就行了,在网上找了 ...
- 关于WCF在IIS8注册的问题
原文 http://social.microsoft.com/Forums/id-ID/30cf8a24-2719-4c1c-b035-3d186fbfc09c/wcfiis8?forum=wcfzh ...
- Oracle中如何插入特殊字符:& 和 ' (多种解决方案)
今天在导入一批数据到Oracle时,碰到了一个问题:Toad提示要给一个自定义变量AMP赋值,一开始我很纳闷,数据是一系列的Insert语句,怎么会有自定义变量呢?后来搜索了一下关键字AMP发现,原来 ...
- Visual Studio Code中文文档
Visual Studio Code中文文档 Visual Studio Code是一个轻量级但是十分强大的源代码编辑器,重要的是它在Windows, OS X 和Linux操作系统的桌面上均可运行. ...
- 基于MMSeg算法的中文分词类库
原文:基于MMSeg算法的中文分词类库 最近在实现基于lucene.net的搜索方案,涉及中文分词,找了很多,最终选择了MMSeg4j,但MMSeg4j只有Java版,在博客园上找到了*王员外*(ht ...