E. Count The Rectangles
There are nnn segments drawn on a plane; the i−thi-thi−th segment connects two points (xi1,yi,1)(x_{i1}, y_{i,1})(xi1,yi,1) and (xi,2,yi,2)(x_{i,2}, y_{i,2})(xi,2,yi,2). Each segment is non-degenerate, and is either horizontal or vertical — formally, for every ?∈[1,?] either xi,1=xi,2x_{i,1}=x_{i,2}xi,1=xi,2 or yi,1=yi,2y_{i,1}=y_{i,2}yi,1=yi,2 (but only one of these conditions holds). Only segments of different types may intersect: no pair of horizontal segments shares any common points, and no pair of vertical segments shares any common points.
We say that four segments having indices h1,h2,v1andv2h_1, h_2, v_1 and v_2h1,h2,v1andv2 such that h1<h2h_1<h_2h1<h2 and v1<v2v_1<v_2v1<v2 form a rectangle if the following conditions hold:
segments h1h_1h1 and h2h_2h2 are horizontal;
segments v1v_1v1 and v2v_2v2 are vertical;
segment h1h_1h1 intersects with segment v1v_1v1;
segment h2h_2h2 intersects with segment v1v_1v1;
segment h1h_1h1 intersects with segment v2v_2v2;
segment h2h_2h2 intersects with segment v2v_2v2.
Please calculate the number of ways to choose four segments so they form a rectangle. Note that the conditions h1<h2h_1<h_2h1<h2 and v1<v2v_1<v_2v1<v2 should hold.
Input
The first line contains one integer n(1≤n≤5000)n (1\leq n\leq 5000)n(1≤n≤5000) — the number of segments.
Then nnn lines follow. The i−thi-thi−th line contains four integers xi,1,yi,1,xi,2x_{i,1}, y_{i,1}, x_{i,2}xi,1,yi,1,xi,2 and yi,2y_{i,2}yi,2 denoting the endpoints of the i−thi-thi−th segment. All coordinates of the endpoints are in the range [−5000,5000][−5000,5000][−5000,5000].
It is guaranteed that each segment is non-degenerate and is either horizontal or vertical. Furthermore, if two segments share a common point, one of these segments is horizontal, and another one is vertical.
Output
Print one integer — the number of ways to choose four segments so they form a rectangle.
Examples
input
7
-1 4 -1 -2
6 -1 -2 -1
-2 3 6 3
2 -2 2 4
4 -1 4 3
5 3 5 1
5 2 1 2
output
7
input
5
1 5 1 0
0 1 5 1
5 4 0 4
4 2 4 0
4 3 4 5
output
0
Note
The following pictures represent sample cases:
题意
- 给你nnn条平行于xxx轴或者yyy轴的直线,求能构成多少个不同的矩形
题解
- 暴力用树状数组维护一下就行了
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=5005;
const int maxl=1e4+2;
int n;
vector<pair<int,int> >hor[maxl],ver[maxl];
vector<int> cur[maxl];
struct node{
int sum[maxl];
int lowbit(int x) {return x&(-x);}
void add(int id,int val){
for(int i=id;i<maxl;i+=lowbit(i)){
sum[i]+=val;
}
}
int query(int id){
int ans=0;
for(int i=id;i>=1;i-=lowbit(i)){
ans+=sum[i];
}
return ans;
}
int s(int l,int r){
return query(r)-query(l-1);
}
void clear(){memset(sum,0,sizeof(sum));}
}bit;
int main()
{
scanf("%d",&n);
for(int i=1,x1,x2,y1,y2;i<=n;i++){
scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
x1+=5001;x2+=5001;y1+=5001;y2+=5001;
if(y1==y2) hor[y1].push_back(make_pair(min(x1,x2),max(x1,x2)));
else ver[x1].push_back(make_pair(min(y1,y2),max(y1,y2)));
}
long long ans=0;
for(int i=1;i<maxl;i++) {
for(auto h1:hor[i]) {
bit.clear();
for(int j=1;j<maxl;j++) cur[j].clear();
for(int j=h1.first;j<=h1.second;j++){
for(auto v:ver[j]){
if(v.first<=i&&v.second>i){
cur[v.second].push_back(j);
bit.add(j,1);
}
}
}
for(int y2=i+1;y2<maxl;y2++){
for(auto h2:hor[y2]) {
int res=bit.s(h2.first,h2.second);
ans+=1LL*res*(res-1)/2;
}
for(auto j:cur[y2]) bit.add(j,-1);
}
}
}
printf("%lld\n",ans);
}