P6149 [USACO20FEB]Triangles S

P6149 [USACO20FEB]Triangles S


思路

  • Runtime Error:读入时+10000,防止work数组内坐标为负数

  • 暴力想到枚举每个三角形直角顶点,优化发现:(截图来自洛谷题解)

  • 想到前缀和三角形面积,比如第一个sort+work,处理以上图x节点为直角顶点的三角形,ans每次加的为以x,y为顶点的前缀面积


代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define mod 1000000007
#define maxn 100005
using namespace std;
int n,cnt_x[maxn],cnt_y[maxn],last_x[maxn],last_y[maxn];
long long ans,sum_x[maxn],sum_y[maxn];
struct fdfdfd{int x,y;}a[maxn];
bool cmp1(fdfdfd a,fdfdfd b){return a.x<b.x||(a.x==b.x&&a.y<b.y);}
bool cmp2(fdfdfd a,fdfdfd b){return a.x<b.x||(a.x==b.x&&a.y>b.y);}
bool cmp3(fdfdfd a,fdfdfd b){return a.x>b.x||(a.x==b.x&&a.y<b.y);}
bool cmp4(fdfdfd a,fdfdfd b){return a.x>b.x||(a.x==b.x&&a.y>b.y);}
void work()
{
	memset(sum_x,0,sizeof(sum_x)); memset(sum_y,0,sizeof(sum_y));
	memset(cnt_x,0,sizeof(cnt_x)); memset(cnt_y,0,sizeof(cnt_y));
	for(int i=1;i<=n;++i)
	{
		int x=a[i].x,y=a[i].y;
		sum_x[x]=(sum_x[x]+(long long)abs(y-last_x[x])*cnt_x[x])%mod;
		++cnt_x[x]; last_x[x]=y;
		sum_y[y]=(sum_y[y]+(long long)abs(x-last_y[y])*cnt_y[y])%mod;
		++cnt_y[y]; last_y[y]=x;
		ans=(ans+sum_x[x]*sum_y[y])%mod;
	}
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;++i) scanf("%d%d",&a[i].x,&a[i].y),a[i].x+=10000,a[i].y+=10000;
	sort(a+1,a+n+1,cmp1); work();
	sort(a+1,a+n+1,cmp2); work();
	sort(a+1,a+n+1,cmp3); work();
	sort(a+1,a+n+1,cmp4); work();
	printf("%lld
",ans);
	return 0;
}
原文地址:https://www.cnblogs.com/wuwendongxi/p/13679822.html