http://acm.hdu.edu.cn/showproblem.php?pid=5862
将竖线(y1 y2 x)拆为两个点 分别在y1 y2+1高度更新x位置 x轴用线段树维护 对于横线(x1 x2 y)就在y高度查询线段树上x1x2对应的区间 这时对应区间里面维护的就是当前高度的横线相交的竖线数量
using namespace std;
struct node1
{
int x1,y1,x2,y2;
};
struct node2
{
int tp;
int x;
};
struct node3
{
int x1;
int x2;
};
node1 pre[100010];
vector <node2> point[200010];
vector <node3> seg[200010];
ll sum[800010];
int tmpx[200010],tmpy[200010];
int n,lenx,leny;
void update(int tar,ll val,int l,int r,int cur)
{
int m;
sum[cur]+=val;
if(l==r) return;
m=(l+r)/2;
if(tar<=m) update(tar,val,l,m,2*cur);
else update(tar,val,m+1,r,2*cur+1);
}
ll query(int pl,int pr,int l,int r,int cur)
{
ll res;
int m;
if(pl<=l&&r<=pr) return sum[cur];
res=0,m=(l+r)/2;
if(pl<=m) res+=query(pl,pr,l,m,2*cur);
if(pr>m) res+=query(pl,pr,m+1,r,2*cur+1);
return res;
}
int main()
{
node2 tmp2;
node3 tmp3;
ll ans;
int t,i,j;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
lenx=0,leny=0;
for(i=1;i<=n;i++)
{
scanf("%d%d%d%d",&pre[i].x1,&pre[i].y1,&pre[i].x2,&pre[i].y2);
tmpx[++lenx]=pre[i].x1,tmpx[++lenx]=pre[i].x2;
tmpy[++leny]=pre[i].y1,tmpy[++leny]=pre[i].y2;
}
sort(tmpx+1,tmpx+lenx+1);
sort(tmpy+1,tmpy+leny+1);
lenx=unique(tmpx+1,tmpx+lenx+1)-tmpx-1;
leny=unique(tmpy+1,tmpy+leny+1)-tmpy-1;
for(i=1;i<=n;i++)
{
pre[i].x1=lower_bound(tmpx+1,tmpx+lenx+1,pre[i].x1)-tmpx;
pre[i].y1=lower_bound(tmpy+1,tmpy+leny+1,pre[i].y1)-tmpy;
pre[i].x2=lower_bound(tmpx+1,tmpx+lenx+1,pre[i].x2)-tmpx;
pre[i].y2=lower_bound(tmpy+1,tmpy+leny+1,pre[i].y2)-tmpy;
}
for(i=0;i<=200000;i++)
{
point[i].clear();
seg[i].clear();
}
for(i=1;i<=n;i++)
{
if(pre[i].x1==pre[i].x2)
{
if(pre[i].y1>pre[i].y2) swap(pre[i].y1,pre[i].y2);
tmp2.tp=1,tmp2.x=pre[i].x1;
point[pre[i].y1].push_back(tmp2);
tmp2.tp=2,tmp2.x=pre[i].x1;
point[pre[i].y2+1].push_back(tmp2);
}
else
{
if(pre[i].x1>pre[i].x2) swap(pre[i].x1,pre[i].x2);
tmp3.x1=pre[i].x1,tmp3.x2=pre[i].x2;
seg[pre[i].y1].push_back(tmp3);
}
}
memset(sum,0,sizeof(sum));
ans=0;
for(i=1;i<=leny;i++)
{
for(j=0;j<point[i].size();j++)
{
if(point[i][j].tp==1) update(point[i][j].x,1,1,lenx,1);
else update(point[i][j].x,-1,1,lenx,1);
}
for(j=0;j<seg[i].size();j++)
{
ans+=query(seg[i][j].x1,seg[i][j].x2,1,lenx,1);
}
}
printf("%lld\n",ans);
}
return 0;
}