2017.9.29 数三角形 思考记录

这个题一看就可以离散、

利用容斥,所以可以用组合数算出所有的三点组合,,再减去在一条线上的点的组合

垂直和水平的好算,斜的就比较繁琐


首先我猜了一个错误的结论:所有直线都可以用左上边界和右下边界的点连接平移而成

然后反例一大堆、

于是又提出了一个错误的结论:原图扩大2倍

然后反例还是一大堆

最终得出结论:原图扩大为原来的平方、、

这次对了,但复杂度不对


但这说明了,所有的直线会受制于边长的限制,边长越小,直线越少

于是就可以想到,从左上角到任意一个点的直线一定包含所有直线。因为如果不从左上角开始,选择的空间一定不会比原来更大

然后就看这个矩形中有多少这样的直线,,来计算对答案的贡献


注意:这样遍历所有同样的直线   会被分成若干小段,所以每次就只需要考虑新加入点(右端点)的贡献


码:

#include<iostream>
#include<cstdio>
using namespace std;
#define ll long long
int gcd(int a,int b)
{
	if(!b)return a;
	return gcd(b,a%b);	
}
ll n,m,ans,i,j;
int main()
{
	scanf("%lld%lld",&n,&m);
	ans=(n+1)*(m+1)*((n+1)*(m+1)-1)*((n+1)*(m+1)-2)/6;
	ans-=((m+1)*m*(m-1)*(n+1)+(n+1)*n*(n-1)*(m+1))/6;
	for(i=0;i<=n;i++)
	for(j=0;j<=m;j++)
	{if(i==0||j==0)continue;
		ans-=1ll*(gcd(i,j)-1)*(m+1-j)*(n+1-i)*2;
	}
	printf("%lld",ans);
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值