给出每个点的横纵坐标 但是只关心纵坐标 每次查询都是x.5的形式 也可以当做查一条长度为1的小线段 一开始所有点都是孤立的 所以不可能会对线段造成什么影响 所有点用并查集维护一下 每次合并点时都把两个子集合在y轴上的最小最大值更新给父结点 先把两个子集合对真个y轴造成的影响去掉 然后把父集合的影响加上去
一开始搞了个离散化 迷之WA 强行暴力AC..
#include <bits/stdc++.h>
using namespace std;
struct node1
{
int l;
int r;
int fa;
int num;
};
struct node2
{
int l;
int r;
int val1;
int val2;
int laz1;
int laz2;
};
node1 uni[100010];
node2 tree[4000010];
int y[100010];
int n,q,ans1,ans2;
void build(int l,int r,int cur)
{
int m;
tree[cur].l=l;
tree[cur].r=r;
tree[cur].val1=0;
tree[cur].val2=0;
tree[cur].laz1=0;
tree[cur].laz2=0;
if(l+1==r) return;
m=(l+r)/2;
build(l,m,2*cur);
build(m,r,2*cur+1);
}
void pushdown(int cur)
{
if(tree[cur].laz1!=0||tree[cur].laz2!=0)
{
tree[2*cur].val1+=tree[cur].laz1;
tree[2*cur].val2+=tree[cur].laz2;
tree[2*cur].laz1+=tree[cur].laz1;
tree[2*cur].laz2+=tree[cur].laz2;
tree[2*cur+1].val1+=tree[cur].laz1;
tree[2*cur+1].val2+=tree[cur].laz2;
tree[2*cur+1].laz1+=tree[cur].laz1;
tree[2*cur+1].laz2+=tree[cur].laz2;
tree[cur].laz1=0,tree[cur].laz2=0;
}
}
void update(int pl,int pr,int val1,int val2,int cur)
{
if(pl<=tree[cur].l&&tree[cur].r<=pr)
{
tree[cur].val1+=val1;
tree[cur].val2+=val2;
tree[cur].laz1+=val1;
tree[cur].laz2+=val2;
return;
}
pushdown(cur);
if(pl<tree[2*cur].r) update(pl,pr,val1,val2,2*cur);
if(pr>tree[2*cur+1].l) update(pl,pr,val1,val2,2*cur+1);
}
void query(int tar,int cur)
{
if(tree[cur].l+1==tree[cur].r)
{
ans1=tree[cur].val1,ans2=tree[cur].val2;
return;
}
pushdown(cur);
if(tar<tree[2*cur].r) query(tar,2*cur);
else query(tar,2*cur+1);
}
int getf(int p)
{
if(uni[p].fa==p) return p;
else
{
uni[p].fa=getf(uni[p].fa);
return uni[p].fa;
}
}
void unite(int u,int v)
{
int fu,fv,l,r;
fu=getf(u);
fv=getf(v);
if(fu!=fv)
{
if(uni[fu].l<uni[fu].r) update(uni[fu].l,uni[fu].r,-1,-uni[fu].num,1);
if(uni[fv].l<uni[fv].r) update(uni[fv].l,uni[fv].r,-1,-uni[fv].num,1);
uni[fv].fa=fu;
l=min(uni[fu].l,uni[fv].l);
r=max(uni[fu].r,uni[fv].r);
uni[fu].l=l,uni[fu].r=r,uni[fu].num+=uni[fv].num;
if(uni[fu].l<uni[fu].r) update(uni[fu].l,uni[fu].r,1,uni[fu].num,1);
}
}
int main()
{
double gou;
int t,i,x,u,v;
char op[10];
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d%d",&x,&y[i]);
uni[i].l=uni[i].r=y[i];
uni[i].fa=i;
uni[i].num=1;
}
build(0,1000000,1);
scanf("%d",&q);
while(q--)
{
scanf("%s",op);
if(op[0]=='r')
{
scanf("%d%d",&u,&v);
u++,v++;
unite(u,v);
}
else
{
scanf("%lf",&gou);
x=gou,ans1=0,ans2=0;
query(x,1);
printf("%d %d\n",ans1,ans2);
}
}
}
return 0;
}