UVALive 4730 Kingdom(线段树区间修改+并查集)
来源:互联网 发布:js 设置session属性值 编辑:程序博客网 时间:2024/05/17 03:00
题意:
有T组测试数据,每组数据的N表示有N个城市,接下来的N行里每行给出每个城市的坐标
(0<=x,y<=1000000) 。
然后有M(1<M<200000) 个操作,操作有两类:
(1)”road A B”,表示将城市A和城市B通过一条道路连接,如果A和B原来属于不同的城市群,经过这个操作,A和B就在一个城市群里了,保证每条道路不会和其他道路相交(除了端点A和B)。
(2)”line C”,表示查询当穿过y=C的直线,有多少个城市群、这几个城市群一共有多少个城市。(注意:C是一个小数位为0.5的小数)
解析:
考录到联通块,所以可以想到用并查集,并查集的根节点保存每个城市群的的最大的y值和最小的y值,以及这个城市群内有多少个点。
每次合并两个集合的时候,先把原先城市群里的东西从线段树里去掉,更新好这个城市群之后,再放下去。
注意:y的范围比较大,又有小数,所以我把y坐标乘2,我把数组开到了200万,结果超时了,后来听了帆神学长的建议,考虑到C是一个小数位为0.5的小数,于是我把所有的左边界前移一位,询问C的时候把C+0.5,这样就避免了小数带来的麻烦,数组只要开到100万就可以过了。
#include <cstdio>#include <cstring>#include <algorithm>#define ls (o<<1)#define rs (o<<1|1)#define lson ls, L, M #define rson rs, M+1, Rusing namespace std;const int MAXY = (int)1e6 + 5;const int MAXN = (int)1e5 + 5;struct Node { int state, city; int adds, addc; //lazy Node() { state = city = adds = addc = 0;}} node[MAXY * 3];int n, q;void build(int o, int L, int R) { node[o] = Node(); if(L == R) return ; int M = (L + R)/2; build(lson); build(rson);}void pushDown(int o) { if(node[o].addc) { node[ls].addc += node[o].addc; node[rs].addc += node[o].addc; node[ls].city += node[o].addc; node[rs].city += node[o].addc; node[o].addc = 0; } if(node[o].adds) { node[ls].adds += node[o].adds; node[rs].adds += node[o].adds; node[ls].state += node[o].adds; node[rs].state += node[o].adds; node[o].adds = 0; }}Node query(int o, int L, int R, int pos) { if(L == R) return node[o]; pushDown(o); int M = (L + R)/2; if(pos <= M) return query(lson, pos); else return query(rson, pos);}void modify(int o, int L, int R, int ql, int qr, int val, char type) { if(ql <= L && R <= qr) { if(type == 'c') { node[o].city += val; node[o].addc += val; }else { node[o].state += val; node[o].adds += val; } return ; } pushDown(o); int M = (L + R)/2; if(ql <= M) modify(lson, ql, qr, val, type); if(qr > M) modify(rson, ql, qr, val, type);}int fa[MAXN];int city[MAXN], state[MAXN], low[MAXN], high[MAXN];void init() { int x, y; for(int i = 0; i < n; i++) { scanf("%d%d", &x, &y); fa[i] = i; city[i] = state[i] = 1; low[i] = high[i] = y; }}int find(int u) { return (fa[u] == u) ? fa[u] : fa[u] = find(fa[u]);}void Union(int u, int v) { int a = find(u), b = find(v); if(a == b) return ; if(low[a] < high[a]) { modify(1, 0, MAXY, low[a]+1, high[a], -city[a], 'c'); modify(1, 0, MAXY, low[a]+1, high[a], -1, 's'); } if(low[b] < high[b]) { modify(1, 0, MAXY, low[b]+1, high[b], -city[b], 'c'); modify(1, 0, MAXY, low[b]+1, high[b], -1, 's'); } if(a > b) swap(a, b); fa[b] = a; low[a] = min(low[a], low[b]); high[a] = max(high[a], high[b]); city[a] += city[b]; state[a] = 1; modify(1, 0, MAXY, low[a]+1, high[a], city[a], 'c'); modify(1, 0, MAXY, low[a]+1, high[a], state[a], 's');}char oper[10];int main() { int T; scanf("%d", &T); while(T--) { scanf("%d", &n); init(); build(1, 0, MAXY); scanf("%d", &q); int u, v; double pos; while(q--) { scanf("%s", oper); if(oper[0] == 'r') { scanf("%d%d", &u, &v); Union(u, v); }else { scanf("%lf", &pos); Node ret = query(1, 0, MAXY, (int)(pos + 1)); printf("%d %d\n", ret.state, ret.city); } } } return 0;}
0 0
- UVALive 4730 Kingdom(线段树区间修改+并查集)
- uvalive 4730王国kingdom(并查集+线段树)
- UVALive 4730 Kingdom 线段树+并查集
- 1455 - Kingdom(并查集+线段树区间加减)
- UVALive 4730 线段树+并查集
- uvalive 4730(并查集+区间修改单点查询)
- LA4730,Kingdom 线段树+并查集
- uva1455 - Kingdom 线段树+并查集
- UVA1455 - Kingdom(并查集 + 线段树)
- Uva4730 Kingdom (并查集+线段树)
- UVALive 4730 Kingdom(并查集加 线段树或树状数组)
- UVA 1455 - Kingdom(线段树+并查集)
- uva 1455 - Kingdom(并查集+线段树)
- UVA 1455 Kingdom(线段树+并查集)
- UVA 1455 Kingdom (线段树 + 并查集 + 离散化)
- UVALive - 4108 SKYLINE (线段树的区间修改)
- UVALive - 4108 SKYLINE 线段树(区间修改)
- UVALive 4108 SKYLINE(线段树区间修改)
- Commons lang3 包ArrayUtils类使用
- 九度OJ 题目1464:Hello World for U
- CompareNoCase与Compare
- 前端学习
- hdu1558(并查集和简单几何的结合)
- UVALive 4730 Kingdom(线段树区间修改+并查集)
- Ubuntu 14.04 FTP服务器--vsftpd的安装和配置
- POJ 1639 最小度限制生成树
- 关于vs2013中使用partial类后仍提示某成员变量不存在时的问题解决
- 隔行变色
- lua 环境设置
- 图片延迟加载
- Eclipse快捷键 10个最有用的快捷键
- 关于函数参数入栈的思考(函数调用约定,入栈顺序)