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(并查集 + 线段树)的更多相关文章

  1. 并查集&线段树&树状数组&排序二叉树

    超级无敌巨牛逼并查集(带权并查集)https://vjudge.net/problem/UVALive-4487 带删点的加权并查集 https://vjudge.net/problem/UVA-11 ...

  2. 【Codeforces576E_CF576E】Painting Edges(可撤销并查集+线段树分治)

    题目 CF576E 分析: 从前天早上肝到明天早上qwq其实颓了一上午MC ,自己瞎yy然后1A,写篇博客庆祝一下. 首先做这题之前推荐一道很相似的题:[BZOJ4025]二分图(可撤销并查集+线段树 ...

  3. BZOJ 3910 并查集+线段树合并

    思路: 1. 并查集+线段树合并 记得f[LCA]==LCA的时候 f[LCA]=fa[LCA] 2.LCT(并不会写啊...) //By SiriusRen #include <cstdio& ...

  4. 并查集 + 线段树 LA 4730 Kingdom

    题目传送门 题意:训练指南P248 分析:第一个操作可以用并查集实现,保存某集合的最小高度和最大高度以及城市个数.运用线段树成端更新来统计一个区间高度的个数,此时高度需要离散化.这题两种数据结构一起使 ...

  5. uvalive 4730王国kingdom(并查集+线段树)

     题意:有T组測试数据.每组数据的N表示有N个城市,接下来的N行里每行给出每一个城市的坐标(0<=x,y<=1000000),然后有M(1<M<200000)个操作,操作有 ...

  6. YYHS-猜数字(并查集/线段树维护)

    题目描述     LYK在玩猜数字游戏.    总共有n个互不相同的正整数,LYK每次猜一段区间的最小值.形如[li,ri]这段区间的数字的最小值一定等于xi.     我们总能构造出一种方案使得LY ...

  7. luogu5012 水の数列 (并查集+线段树)

    如果我们能求出来每个区间个数的最大分值,那就可以用线段树维护这个东西 然后出答案了 然后这个的求法和(luogu4269)Snow Boots G非常类似,就是我们把数大小排个序,每次都拿<=x ...

  8. 【CF471E】MUH and Lots and Lots of Segments 扫描线+并查集+线段树+set

    [CF471E]MUH and Lots and Lots of Segments 题意:给你平面上n条水平或竖直的,端点在整点处的线段.你需要去掉一些线段的一些部分,使得剩下的图形:1.连通,2.无 ...

  9. 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 ...

随机推荐

  1. MongoDB---性能优化---(1)

    MONGODB数据架构 升级解决.计划 发现问题  应用server用户数的突然涌入,创建server反应慢  检查server,我发现,每次反应非常慢,至30ops  检查过程  .发现数据库查询缓 ...

  2. password学3——Java BASE64加密解密

    Base64是网络上最常见的用于传输8Bit字节代码的编码方式之中的一个,大家能够查看RFC2045-RFC2049.上面有MIME的具体规范.Base64编码可用于在HTTP环境下传递较长的标识信息 ...

  3. ubuntu 常用软件

    terminator:任意分割控制台 Sublime Text:文本编辑器,也是轻量级的IDE Wireshark:抓包工具 Okular:PDF等文档编辑工具 yEd:流程图等制图软件 Shutte ...

  4. linux命令: sort

    参考 linux sort 命令详解 http://www.cnblogs.com/51linux/archive/2012/05/23/2515299.html 1 sort的工作原理 sort将文 ...

  5. windows 2003 域控制器(AD)的常规命令行操作以及修复

    查询服务器的角色 Netdom query fsmo 强制升级操作主机角色(如果两台DC都无损,可以直接用图形模式传送,这里指的是一台DC出问题,另一台强制升级占用角色的情况) Ntdsutil Ro ...

  6. MFC画二维动态图表[GDI]

    源博客:http://www.codeproject.com/Articles/9350/2D-Animated-Charts 源代码:http://download.csdn.net/detail/ ...

  7. 发现CSDN的一个小Bug,CSDN网站管理人员进来看看哈~~

    CSDN发博文的时候,说转载和翻译的博文不能被推荐到CSDN首页 刚刚我转了一个好的文章,一开始确实“发布到CSDN博客首页”的选项没了,但是之后我发现这个文章我要做点修改,就点击了编辑 之后这个选项 ...

  8. NX-bridge,可以实现无线XBee控制的Arduino板

    ”今天Elecfreaks Studio给你介绍一个新的.很实用的朋友:带有一些奇幻色彩的神秘设备.它是什么呢?它可以完成什么功能呢?它对我们的生活有哪些促进呢?非常感兴趣吧?别着急,我们这就给您详细 ...

  9. uva 1346 - Songs(贪心)

    题目链接:uva 1346 - Songs 题目大意:John Doe 是一个著名的DJ,现在他有n首播放个曲, 每首歌曲有识别符key,歌曲长度l,以及播放频率q.想在John Doe 想将磁带上的 ...

  10. SDUT Fermat’s Chirstmas Theorem(素数筛)

    Fermat's Chirstmas Theorem Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描写叙述 In a letter ...