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);elseans = 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. 暑期集训5:并查集 线段树 练习题G: HDU - 1754

    2018学校暑期集训第五天--并查集 线段树 练习题G  --   HDU - 1754 I Hate It 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.  这让 ...

  2. 暑期集训5:并查集 线段树 练习题F:  HDU - 1166 ​​​​​​​

    2018学校暑期集训第五天--并查集 线段树 练习题F  --   HDU - 1166 敌兵布阵 C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A ...

  3. 暑期集训5:并查集 线段树 练习题B: HDU - 1213 ​​​​​​​

    2018学校暑期集训第五天--并查集 线段树 练习题B  --   HDU - 1213 How Many Tables Today is Ignatius' birthday. He invites ...

  4. 暑期集训5:并查集 线段树 练习题A:  HDU - 1232 ​​​​​​​

    2018学校暑期集训第五天--并查集 线段树 练习题A  --   HDU - 1232 畅通工程 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府"畅 ...

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

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

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

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

  7. 线段树分治 ---- CF1217F - Forced Online Queries Problem(假离线 可撤销并查集 + 线段树分治)详解

    题目链接 题目大意 解题思路: 我一开始想到可以用可撤销并查集去维护这种删边加边的操作,但是有个缺点是每次撤销都有把后面的边全部撤销复度是O(n2)O(n^2)O(n2) 首先我们考虑这种动态加边删边 ...

  8. poj 2985(并查集+线段树求K大数)

    解题思路:这道题并查集很容易,合并时找到父节点就直接加上去就ok了.关键是如何求K大数,我一直在想用线段树怎么写,一开始想如果直接记录数的大小那肯定是没戏了,借鉴了一下别人的思路:区间[a,b]记录的 ...

  9. 【BZOJ4025】二分图(可撤销并查集+线段树分治)

    题目: BZOJ4025 分析: 定理:一个图是二分图的充要条件是不存在奇环. 先考虑一个弱化的问题:保证所有边出现的时间段不会交叉,只会包含或相离. 还是不会?再考虑一个更弱化的问题:边只会出现不会 ...

最新文章

  1. 为什么说 Java 程序员到了必须掌握 Spring Boot 的时候?
  2. WinDbg配置和使用基础
  3. 用putty生成密钥SSH远程登录(解决)
  4. Pytorch实战1:线性回归(Linear Regresion)
  5. php v9 如何获取超级管理员权限,phpcms v9 增加后台管理员其他权限角色可以查看信息不能修改信息...
  6. 手机版腐蚀rust_手机进水后黑屏,该怎么办?切忌做这几件事
  7. 【BZOJ3729】Gty的游戏,博弈+splay
  8. svn: E155036: Please see the ‘svn upgrade‘
  9. 毕业或者想转行做c++服务端开发的时候都很迷茫不知道从哪里开始学习?
  10. C语言实现推箱子游戏完整代码
  11. c语言数学函数指数,C语言数学函数参考表
  12. jqurey怎么写入html,html如何写入和创建功能到jquery
  13. JVM内存模型、原理、垃圾回收、调优
  14. Markdown入门总结
  15. Android FrameWork Input触控事件处理流程 笔记
  16. 2022年自考专业(工商企业管理)企业管理概论练习题
  17. 华硕ProArt 创16体验:全新交互+顶级屏幕 更匹配创作的笔记本
  18. 联阳IT6561|IT6561FN方案电路|替代IT6561方案设计DP转HDMI音视频转换器资料
  19. Mac下破解百度网盘限速(Chrome + Aria2GUI)
  20. 帆软报错11300001

热门文章

  1. PowerPC VxWorks BSP分析7——image压缩
  2. CentOS Samba 服务器的构建(转)
  3. VMware Workstation 6.0全貌概览
  4. H264码流中SPS PPS
  5. mysql排序空的放后面_mysql排序让空值NULL排在数字后边-Fun言
  6. python写炒股软件_利用 Python 构建自己的股票投资系统
  7. 教你如何使用Solitude评估应用程序中的用户隐私问题
  8. c语言退格的值是多少,在c语言里enter的键值是多少啊?
  9. 小A与任务 (贪心 优先队列)
  10. 线段树 ---- Codeforces 737 Div2 D. Ezzat and Grid 维护dp