题意:有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;
}