LA4730 UVA1455 线段树+并查集
2016-11-20 22:14
288 查看
以y轴建线段树 把坐标*2 初始化各节点 洲,城市 数目为0
并查集维护每一个连通块的 y坐标最大值最小值(x坐标没用)城市数目
合并时 如果是一个洲(城市数大于1) 线段树对应区间减掉该洲城市数
然后将两个洲合并,再在线段树对应区间增加大洲的城市数
(区间城市数不等于子区间城市数之和)
并查集维护每一个连通块的 y坐标最大值最小值(x坐标没用)城市数目
合并时 如果是一个洲(城市数大于1) 线段树对应区间减掉该洲城市数
然后将两个洲合并,再在线段树对应区间增加大洲的城市数
(区间城市数不等于子区间城市数之和)
#include <bits/stdc++.h> using namespace std; const int Maxn=2e6+80; int f[Maxn]; struct node { int l,r,city,zhou,addc,addz; int mid() { return (l+r)/2; } } tree[Maxn<<2]; struct point { int maxn,minv,city,zhou; }; point p[Maxn]; int findset(int u) { return u==f[u]?u:f[u]=findset(f[u]); } void build(int node,int l,int r) { tree[node].l=l,tree[node].r=r; tree[node].city=tree[node].zhou=tree[node].addc=tree[node].addz=0; if(l==r) return; build(node<<1,l,(r+l)>>1); build(node<<1|1,(r+l)/2+1,r); } void pushdown(int node) { if(tree[node].addc) { tree[node<<1].city+=tree[node].addc; tree[node<<1|1].city+=tree[node].addc; tree[node<<1].addc+=tree[node].addc; tree[node<<1|1].addc+=tree[node].addc; tree[node].addc=0; } if(tree[node].addz) { tree[node<<1].zhou+=tree[node].addz; tree[node<<1|1].zhou+=tree[node].addz; tree[node<<1].addz+=tree[node].addz; tree[node<<1|1].addz+=tree[node].addz; tree[node].addz=0; } } void update(int node,int l,int r,int city,int zhou) { if(tree[node].l==l&&r==tree[node].r) { tree[node].city+=city; tree[node].zhou+=zhou; tree[node].addc+=city; tree[node].addz+=zhou; return ; } pushdown(node); int mid=tree[node].mid(); if(mid<l) { update(node<<1|1,l,r,city,zhou); } else if(mid>=r) { update(node<<1,l,r,city,zhou); } else { update(node<<1,l,mid,city,zhou); update(node<<1|1,mid+1,r,city,zhou); } } int query(int node,int l,int r) { if(tree[node].l==l&&r==tree[node].r) { return node; } int mid=tree[node].mid(); pushdown(node); if(mid<l) { query(node<<1|1,l,r); } else if(mid>=r) { query(node<<1,l,r); } else { query(node<<1,l,mid); query(node<<1|1,mid+1,r); } } void un(int x,int y) { int _x=findset(x),_y=findset(y); if(f[_x]==f[_y]) { return ; } f[_x]=_y; if(p[_x].city>1) update(1,p[_x].minv,p[_x].maxn,-p[_x].city,-1); if(p[_y].city>1) update(1,p[_y].minv,p[_y].maxn,-p[_y].city,-1); p[_y].maxn=max(p[_x].maxn,p[_y].maxn); p[_y].minv=min(p[_y].minv,p[_x].minv); p[_y].city+=p[_x].city; update(1,p[_y].minv,p[_y].maxn,p[_y].city,1); } int t,n,m; int yy[Maxn]; int main() { scanf("%d",&t); while(t--) { int x,y,Max=0; scanf("%d",&n); for(int i =1; i<=n; ++i) f[i]=i; for(int i = 1; i <= n; ++i) { scanf("%d%d",&x,&y); yy[i]=y*2; Max=max(Max,yy[i]); p[i].minv=p[i].maxn=y*2; p[i].city=1; p[i].zhou=1; } build(1,0,Max); for(int i = 1; i<= n; ++i) update(1,yy[i],yy[i],1,1); scanf("%d",&m); char ch[10]; double pos; for(int i = 0; i < m; ++i) { scanf("%s",ch); if(ch[0]=='r') { scanf("%d%d",&x,&y); un(x+1,y+1); } else { scanf("%lf",&pos); if(pos*2>Max) printf("0 0\n"); else { int no=query(1,pos*2,pos*2); printf("%d %d\n",tree[no].zhou,tree[no].city); } } } } return 0; }
相关文章推荐
- UVa 1455 Kingdom 线段树 并查集
- UVA 1455 Kingdom (线段树 + 并查集 + 离散化)
- UVA1455 - Kingdom(并查集 + 线段树)
- UVA 11987 Almost Union-Find (带权并查集的操作及并查集的删除操作)
- floyd闭包或者加一点并查集uva247
- 【UVALive】6168 Fat Ninjas 并查集
- UVa - 10608 Friends (并查集)
- uva 10608 并查集个数
- Corporative Network UVA - 1329 加权并查集(压缩路径优化)
- UVALive 3027 并查集
- uva 10608(并查集)
- UVALive 3027 Corporative Network (带权并查集)
- UVa 10158 War / 并查集
- UVALive 4730 -树状数组+带权并查集
- uva 11987 带删除的并查集
- UVA - 10608 Friends 并查集水题
- uvalive 3027(并查集)
- UVALive 4730 Kingdom(线段树区间修改+并查集)
- 指南 第三章 例题6 UVALive 3027 Corporative Network(并查集的应用)
- uvalive 3027 Corporative Network(种类并查集)