Triangles S 题解

P6149 [USACO20FEB] Triangles S - 洛谷 (luogu.com.cn)
题解:P6149 [USACO20FEB] Triangles S - 洛谷专栏 (luogu.com.cn)
对于一个点考虑它与它横坐标相等和纵坐标相等的点,假设有两个点与它横坐标相等,纵坐标小于它,另两个点与它纵坐标相等,横坐标小于它。假设与它横坐标相等的两个点离它的距离是 a,a+b,另外两个点离这个点的纵坐标的距离是 c,c+d,那么贡献就是 ac+a(c+d)+c(a+b)+(a+b)(c+d)=(2a+b)(2c+d)),一个另个相邻点的线段的贡献次数就是比他远的点的数量。

先按横坐标排序再按纵坐标排序,分别统计贡献,这里还要考虑不同的四个方向,对于横坐标排序预处理一个点往左右的贡献,纵坐标排序预处理一个点往上下的贡献,最后把贡献求和,就是把四个方向的答案相加。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5,Mod=1e9+7;
int n,sum,ans,ly[N],ry[N],ux[N],dx[N];
struct node
{
	int x,y,id;
}a[N];
bool cmp1(node x,node y)
{
	if(x.x==y.x) return x.y<y.y;
	return x.x<y.x;
}
bool cmp2(node x,node y)
{
	if(x.y==y.y) return x.x<y.x;
	return x.y<y.y;
}
signed main()
{
	cin>>n;
	for(int i=1;i<=n;++i) cin>>a[i].x>>a[i].y,a[i].x+=1e4+5,a[i].y+=1e4+5,a[i].id=i;
	sort(a+1,a+1+n,cmp1);
	for(int i=1;i<=n;++i)
	{
		int m=i;
		while(a[i].x==a[m+1].x) m++;
		sum=0;
		for(int j=i+1;j<=m;++j)
		{
			sum++;
			ly[a[j].id]=ly[a[j-1].id]+sum*(a[j].y-a[j-1].y);
			ly[a[j].id]%=Mod;
		}
		sum=0;
		for(int j=m-1;j>=i;--j)
		{
			sum++;
			ry[a[j].id]=ry[a[j+1].id]+sum*(a[j+1].y-a[j].y);
			ry[a[j].id]%=Mod;
		}
		i=m;
	}
	sort(a+1,a+1+n,cmp2);
	for(int i=1;i<=n;++i)
	{
		int m=i;
		while(a[i].y==a[m+1].y) m++;
		sum=0;
		for(int j=i+1;j<=m;++j)
		{
			sum++;
			ux[a[j].id]=ux[a[j-1].id]+sum*(a[j].x-a[j-1].x);
			ux[a[j].id]%=Mod;
		}
		sum=0;
		for(int j=m-1;j>=i;--j)
		{
			sum++;
			dx[a[j].id]=dx[a[j+1].id]+sum*(a[j+1].x-a[j].x);
			dx[a[j].id]%=Mod;
		}
		i=m;
	}
	for(int i=1;i<=n;++i) ans+=ly[i]*ux[i]+ly[i]*dx[i]+ry[i]*ux[i]+ry[i]*dx[i],ans%=Mod;
	cout<<ans;
	return 0;
}

啊?AC代码现在让发了?

错误的,应该是隔壁直接复制过来忘删了,已更

反正题解里也能看到我代码

我觉得不用删

@稻叶昙 @刘子睿 反正,你提交金杭东巨佬的代码就是抄题解

那算了就这样吧