题意:有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的直线,有多少个城市群、这几个城市群一共有多少个城市。
用并查集维护每个城市群的的最大的y值和最小的y值,以及这个城市群内有多少个点。
每次更新的时候,先把原先城市群里的东西从线段树里去掉,更新好这个城市群之后,再放下去。
不过,用线段树要离散化,麻烦了点,写了两树状数组。分别维护有多少个state和city.
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int N=2000005; int y[N]; int fa[N],irank[N],iy1[N],iy2[N]; int find_fa(int x) { if(fa[x]==x) return x; else return fa[x]=find_fa(fa[x]); } void unin(int a,int b) { int x=find_fa(a),y=find_fa(b); if(x==y) return; else { fa[x]=y; irank[y]+=irank[x]; } } struct BIT { int data[N],limit; void init(int a) { limit=a; memset(data,0,sizeof(int)*(limit+5)); } void updata(int x,int y,int valu) { while(x>=1) { data[x]-=valu; x-=(x&(-x)); } while(y>=1) { data[y]+=valu; y-=(y&(-y)); } } int query(int x) { int sum=0; while(x<=limit) { sum+=data[x]; x+=(x&(-x)); } return sum; } }state,city; int main() { int t; scanf("%d",&t); while(t--) { int n,m,imax=0; scanf("%d",&n); for(int i=0;i<n;i++) { int a,b; scanf("%d%d",&a,&b); b*=2; y[i]=b; fa[i]=i; irank[i]=1; iy1[i]=b; iy2[i]=b; imax=max(imax,b); } state.init(imax); city.init(imax); scanf("%d",&m); for(int i=0;i<m;i++) { char str[30]; scanf("%s",str); if(strcmp(str,"road")==0) { int a,b,x,y; scanf("%d%d",&a,&b); x=find_fa(a),y=find_fa(b); if(x==y) continue; if(irank[x]==1&&irank[y]==1) { unin(a,b); int fa=find_fa(a); iy1[fa]=min(iy1[a],iy1[b]); iy2[fa]=max(iy2[a],iy2[b]); state.updata(iy1[fa]-1,iy2[fa],1); city.updata(iy1[fa]-1,iy2[fa],irank[fa]); } else if(irank[x]==1||irank[y]==1) { if(irank[x]==1) swap(x,y); state.updata(iy1[x]-1,iy2[x],-1); city.updata(iy1[x]-1,iy2[x],-irank[x]); unin(a,b); int fa=find_fa(a); iy1[fa]=min(iy1[fa],min(iy1[x],iy1[y])); iy2[fa]=max(iy2[fa],max(iy2[x],iy2[y])); state.updata(iy1[fa]-1,iy2[fa],1); city.updata(iy1[fa]-1,iy2[fa],irank[fa]); } else { state.updata(iy1[x]-1,iy2[x],-1); state.updata(iy1[y]-1,iy2[y],-1); city.updata(iy1[x]-1,iy2[x],-irank[x]); city.updata(iy1[y]-1,iy2[y],-irank[y]); unin(a,b); int fa=find_fa(a); iy1[fa]=min(iy1[fa],min(iy1[x],iy1[y])); iy2[fa]=max(iy2[fa],max(iy2[x],iy2[y])); state.updata(iy1[fa]-1,iy2[fa],1); city.updata(iy1[fa]-1,iy2[fa],irank[fa]); } } else { int a,b; scanf("%d.%d",&a,&b); printf("%d %d\n",state.query(a*2+1),city.query(a*2+1)); } } } return 0; }