因为c是小数,那么把c向上取整,区间低加一就可以了,其他的线段树维护。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100000+5;
struct Interval{
int sumv[5][maxn*4],addv[5][maxn*4];
void clear() {
memset(sumv[0],0,sizeof(sumv)[0]);memset(addv[0],0,sizeof(addv[0]));
memset(sumv[1],0,sizeof(sumv)[1]);memset(addv[1],0,sizeof(addv[1]));
}
void pushup(int o){
sumv[0][o]=sumv[0][o*2]+sumv[0][o*2+1];
sumv[1][o]=sumv[1][o*2]+sumv[1][o*2+1];
}
void pushdown(int o){
int lc=o*2,rc=o*2+1;
if(addv[0][o]){
sumv[0][lc]+=addv[0][o];
sumv[0][rc]+=addv[0][o];
addv[0][lc]+=addv[0][o];
addv[0][rc]+=addv[0][o];
addv[0][o]=0;
}
if(addv[1][o]){
sumv[1][lc]+=addv[1][o];
sumv[1][rc]+=addv[1][o];
addv[1][lc]+=addv[1][o];
addv[1][rc]+=addv[1][o];
addv[1][o]=0;
}
}
void update(int o,int L,int R,int l,int r,int v,int id)
{
if(l>r) return ;
if(l<=L&&R<=r){
sumv[id][o]+=v;
addv[id][o]+=v;
return ;
}
pushdown(o);
int mid=(L+R)/2;
if(l<=mid) update(o*2,L,mid,l,r,v,id);
if(r>mid) update(o*2+1,mid+1,R,l,r,v,id);
pushup(o);
}
int query(int o,int L,int R,int c)
{
if(L==R) return o;
pushdown(o);
int mid=(L+R)/2;
if(c<=mid) return query(o*2,L,mid,c);
if(c>mid) return query(o*2+1,mid+1,R,c);
return 0;
}
};
Interval tree;
int down[maxn],up[maxn],tot[maxn],pa[maxn];
int findset(int x) {return pa[x]==x?x:pa[x]=findset(pa[x]);}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
tree.clear();
int x,y,n,maxy=0;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d%d",&x,&y);
pa[i]=i;
tot[i]=1;
down[i]=up[i]=y;
maxy=max(maxy,y);
}
maxy++;
int q;
char cmd[10];
scanf("%d",&q);
while(q--)
{
scanf("%s",cmd);
if(cmd[0]=='r'){
scanf("%d%d",&x,&y);
int px=findset(x);
int py=findset(y);
if(px!=py){
if(up[px]>up[py]) swap(px,py);
if(up[px]<down[py])
{
tree.update(1,1,maxy,up[px]+1,down[py],1,0);
tree.update(1,1,maxy,up[px]+1,down[py],tot[px]+tot[py],1);
tree.update(1,1,maxy,down[px]+1,up[px],tot[py],1);
tree.update(1,1,maxy,down[py]+1,up[py],tot[px],1);
}
else if(down[px]>down[py])
{
tree.update(1,1,maxy,down[px]+1,up[px],-1,0);
tree.update(1,1,maxy,up[px]+1,up[py],tot[px],1);
tree.update(1,1,maxy,down[py]+1,down[px],tot[px],1);
}
else
{
tree.update(1,1,maxy,down[py]+1,up[px],-1,0);
tree.update(1,1,maxy,up[px]+1,up[py],tot[px],1);
tree.update(1,1,maxy,down[px]+1,down[py],tot[py],1);
}
pa[px]=py;
tot[py]+=tot[px];
down[py]=min(down[py],down[px]);
up[py]=max(up[py],up[px]);
}
}
else{
double c;
scanf("%lf",&c);
int o=tree.query(1,1,maxy,(int)(c+1));
printf("%d %d\n",tree.sumv[0][o],tree.sumv[1][o]);
}
}
}
return 0;
}