Title description
Farmer John wants to build a triangular pasture for his cows. There are N (3≤N≤10 ^ 5) fence posts located at different points (X1, Y1) ... (XN, YN) on the two-dimensional plane of the farm. He can choose three points to form a triangle pasture, as long as one side of the triangle is parallel to the x-axis and the other side is parallel to the y-axis.
What is the sum of all possible pasture areas that FJ can make up?
Input
The first line contains N.
Each of the following N rows contains two integers Xi and Yi, both in the range −10 4… 10 4, describing the position of a fence post.
Output
Since the sum of areas is not necessarily an integer and may be very large, the remainder of the output area is twice the modulus 10 ^ 9 + 7.
Sample input
4
0 0
0 1
1 0
1 2
Sample output
3
Data range limitation
Test points 1-2 satisfy N = 200.
Test points 3-4 satisfy N≤5000.
Test points 5-10 have no additional restrictions.
prompt
Fence stakes (0,0), (1,0) and (1,2) form a triangle of area 1, (0,0), (1,0) and (0,1) form an area The triangle is 0.5. So the answer is 2 * (1 + 0.5) = 3.
analysis
Now this %% beginend big brother.
The magic method taught by the big brother. It is to sort the horizontal and vertical coordinates of all points, and then do the prefix sum. Calculate s1 and s2 for each point, and multiply all s1 and s2 and add up.
s1 is long. s2 is wide.
Code on
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int mod=1000000007;
long long n,s[100001],s1[100001],s2[100001];
long long ans;
struct node
{
int x,y,id;
}a[100001];
int cmp(node l,node r)
{
return l.x<r.x||l.x==r.x&&l.y<r.y;
}
int cmp1(node l,node r)
{
return l.y<r.y||l.y==r.y&&l.x<r.x;
}
int main()
{
freopen("triangles.in","r",stdin);
freopen("triangles.out","w",stdout);
cin>>n;
for(register int i=1;i<=n;i++)
{
cin>>a[i].x>>a[i].y;
a[i].id=i;
}
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++)
{
int j=i;
while(j<n&&a[j+1].x==a[j].x) j++;
s[i-1]=0;
for(int k=i;k<=j;k++) s[k]=s[k-1]+a[k].y;
for(int k=i;k<=j;k++)
{
s1[a[k].id]=s[j]-s[k]-(j-k)*a[k].y+(k-i)*a[k].y-(s[k-1]-s[i-1]);
}
i=j;
}
sort(a+1,a+n+1,cmp1);
for(int i=1;i<=n;i++)
{
int j=i;
while(j<n&&a[j+1].y==a[j].y) j++;
s[i-1]=0;
for(int k=i;k<=j;k++) s[k]=s[k-1]+a[k].x;
for(int k=i;k<=j;k++)
{
s2[a[k].id]=s[j]-s[k]-(j-k)*a[k].x+(k-i)*a[k].x-(s[k-1]-s[i-1]);
}
i=j;
}
for(int i=1;i<=n;i++)
{
ans+=(s1[i]*s2[i])%mod;
}
cout<<ans%mod;
fclose(stdin);
fclose(stdout);
return 0;
}
Big brother's brain circuit is a bit strange. . .