【UVA1455】Kingdom
2017-10-20 19:33
381 查看
题意
有n个点和m个操作,分为两种:
①.road u v表示连接u号点和v号点
②.line C(C为小数,并且小数部分一定为0.5)表示询问y=C这条直线穿越了几个联通块,这些联通块的点数之和是多少
n≤105,m≤2∗105
解法
并查集+线段树:
一开始错的很惨啊……不过最后还是自己改出来了……
运行速度还是挺快的,在这里排Rank3
对于连边操作,应该想到并查集,同时维护每一个并查集的siz,这个很容易实现,难点是②操作:
因为询问比较多,所以单次询问的复杂度应该在logn级别,大家应该都会想到线段树
对于一个联通块S,考虑再维护两个信息:下边界和上边界(y轴方向上),在合并两个并查集的时候,同时更新这两个信息:
然后我们就可以将每一个联通块对应在线段树上的一个区间,这样我们就可以利用线段树做到log的查询,下面考虑怎么维护区间信息:
假设目前要合并两个联通块S和U,那么应该首先去除掉这两个联通块原本的贡献,然后合并之后加上新联通块的贡献,这样就不会有重复
所以我们在线段树中记录区间左右端点,完全覆盖了这一个区间的联通块个数以及这些联通块中的点数之和(完全覆盖指这一个区间是某个联通块的覆盖范围的子集)
在进行区间操作时,因为覆盖的区间长度可能比较大,所以肯定不能够暴力覆盖所有的单点,而是要打lazy标记。不过本题的区间维护很特殊,并不能够通过子节点来更新父节点,而只能够通过父节点更新子节点:因为如果某个联通块完全覆盖了某个区间u,但是并不一定完全覆盖了u的父节点,相反,u的子节点一定会被完全覆盖
然后还有一个问题就是C是一个小数,这让我们很恼火。不过可以将每一个点的纵坐标都乘以2,然后C也乘以2,这样的话就可以把所有的点变为整数,不过相应的,空间也要开两倍大(我就是这里被坑了好久……数组开小了可能是RE,可能会WA,也有可能导致TLE)
复杂度
O(T∗mlogn)
代码
有n个点和m个操作,分为两种:
①.road u v表示连接u号点和v号点
②.line C(C为小数,并且小数部分一定为0.5)表示询问y=C这条直线穿越了几个联通块,这些联通块的点数之和是多少
n≤105,m≤2∗105
解法
并查集+线段树:
一开始错的很惨啊……不过最后还是自己改出来了……
运行速度还是挺快的,在这里排Rank3
对于连边操作,应该想到并查集,同时维护每一个并查集的siz,这个很容易实现,难点是②操作:
因为询问比较多,所以单次询问的复杂度应该在logn级别,大家应该都会想到线段树
对于一个联通块S,考虑再维护两个信息:下边界和上边界(y轴方向上),在合并两个并查集的时候,同时更新这两个信息:
然后我们就可以将每一个联通块对应在线段树上的一个区间,这样我们就可以利用线段树做到log的查询,下面考虑怎么维护区间信息:
假设目前要合并两个联通块S和U,那么应该首先去除掉这两个联通块原本的贡献,然后合并之后加上新联通块的贡献,这样就不会有重复
所以我们在线段树中记录区间左右端点,完全覆盖了这一个区间的联通块个数以及这些联通块中的点数之和(完全覆盖指这一个区间是某个联通块的覆盖范围的子集)
在进行区间操作时,因为覆盖的区间长度可能比较大,所以肯定不能够暴力覆盖所有的单点,而是要打lazy标记。不过本题的区间维护很特殊,并不能够通过子节点来更新父节点,而只能够通过父节点更新子节点:因为如果某个联通块完全覆盖了某个区间u,但是并不一定完全覆盖了u的父节点,相反,u的子节点一定会被完全覆盖
然后还有一个问题就是C是一个小数,这让我们很恼火。不过可以将每一个点的纵坐标都乘以2,然后C也乘以2,这样的话就可以把所有的点变为整数,不过相应的,空间也要开两倍大(我就是这里被坑了好久……数组开小了可能是RE,可能会WA,也有可能导致TLE)
复杂度
O(T∗mlogn)
代码
#include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #define ls 2*k #define rs 2*k+1 #define Rint register int #define Lint long long int using namespace std; const int N=2000100; int up ,down ; int f ,siz ; int T,n,m; struct Segment_tree { struct node { int l,r; int cnt,siz; }t[N*4]; struct task { int cnt,siz; }A; void build(Rint k,Rint l,Rint r) { t[k].l=l,t[k].r=r; if( l==r ) return ; int mid=(l+r)/2; build( ls,l,mid ),build( rs,mid+1,r ); } void pushdown(Rint k) { if( ls>N*4 ) return ; int &x=t[k].cnt,&y=t[k].siz; t[ls].cnt+=x,t[rs].cnt+=x; t[ls].siz+=y,t[rs].siz+=y; x=y=0; } void insert(Rint k,Rint l,Rint r,Rint x,Rint w) { if( ( k==1 && l==r ) || l>r ) return ; if( t[k].l==l && t[k].r==r ) { t[k].cnt+=w,t[k].siz+=w*siz[x]; return ; } pushdown( k ); if( r<=t[ls].r ) insert( ls,l,r,x,w ); else if( l>=t[rs].l ) insert( rs,l,r,x,w ); else insert( ls,l,t[ls].r,x,w ),insert( rs,t[rs].l,r,x,w ); } task query(Rint k,Rint x) { if( t[k].l==t[k].r ) return (task){ t[k].cnt,t[k].siz }; pushdown( k ); if( x<=t[ls].r ) return query( ls,x ); else return query( rs,x ); } void clear(Rint k,Rint l,Rint r) { t[k].l=0,t[k].r=0; t[k].cnt=t[k].siz=0; if( l==r ) return ; int mid=(l+r)/2; clear( ls,l,mid ),clear( rs,mid+1,r ); } }Tr; int find(int x) { if( x!=f[x] ) f[x]=find( f[x] ); return f[x]; } void Union(int u,int v) { f[u]=v; siz[v]+=siz[u]; up[v]=max( up[v],up[u] ); down[v]=min( down[v],down[u] ); } int main() { char s[10]; double x; int u,v,mx; scanf("%d",&T); while( T-- ) { scanf("%d",&n); mx=0; for(int i=1;i<=n;i++) f[i]=i,siz[i]=1; for(int i=1;i<=n;i++) { scanf("%d%d",&u,&v); up[i]=down[i]=v*2; mx=max( mx,v ); } mx=mx*2; Tr.build( 1,1,mx ); scanf("%d",&m); while( m-- ) { scanf("%s",s); if( s[0]=='r' ) { scanf("%d%d",&u,&v); u++,v++; u=find( u ),v=find( v ); if( u!=v ) { Tr.insert( 1,down[u]+1,up[u],u,-1 ); Tr.insert( 1,down[v]+1,up[v],v,-1 ); Union( u,v ); Tr.insert( 1,down[v]+1,up[v],v,1 ); } } else { scanf("%lf",&x); v=x*2; if( v>mx ) { printf("0 0\n");continue ; } Tr.A=Tr.query( 1,v ); printf("%d %d\n",Tr.A.cnt,Tr.A.siz); } } Tr.clear( 1,1,mx ); } return 0; }
相关文章推荐
- UVa 1455 Kingdom 线段树 并查集
- UVA 1455 Kingdom(线段树+并查集)
- uva 1455 - Kingdom(并查集+线段树)
- UVA1455 - Kingdom(并查集 + 线段树)
- uva1455 - Kingdom 线段树+并查集
- UVA 1455 - Kingdom(线段树+并查集)
- UVA 1455 Kingdom (线段树 + 并查集 + 离散化)
- uva 1455 王国
- HDU 1455 POJ 1011 UVA 307 Sticks
- 1455 - Kingdom(并查集+线段树区间加减)
- UVALive 4730 Kingdom(并查集加 线段树或树状数组)
- hduoj 1455 && uva 243 E - Sticks
- Uva4730 Kingdom (并查集+线段树)
- 1455 - Kingdom
- 【UVa 1670/Uvalive 5920】 Kingdom Roadmap 图论
- uva 1670 Kingdom Roadmap(图论构造题)
- UVALive 4730 Kingdom 线段树+并查集
- UVALive 4730 - Kingdom 树状数组区间修改单点查询
- uvalive 4730王国kingdom(并查集+线段树)
- UVALive 4730 Kingdom(线段树区间修改+并查集)