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万就可以过了。

my code

#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
原创粉丝点击