2020 Winter Holiday 【gmoj2411】 【Triangles】

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. . .

Published 110 original articles · 100 praises · 8001 views

Guess you like

Origin blog.csdn.net/dglyr/article/details/105678221