bzoj3505

ans=C((n+1)*(m+1),3)-三点一线的情况
横线竖线我们可以先去掉
然后考虑斜线,由于对称性我们只要考虑斜率大于0的即可
有一个很显然的结论,但两点坐标差为x,y时,这条线段上的点数为gcd(x,y)
我们设左下角点为(0,0),则两端点坐标差为x,y的线段有(n-x+1)*(m-y+1)
要注意同在一条直线上不能重复计算,我们考虑线段更容易一点
所以,对于每条线段,三点一线的情况为除去两端点的线段上点数

 1 var i,j,n,m:longint;
 2     ans,tmp:int64;
 3 function calc(x:int64):int64;
 4   begin
 5     exit(x*(x-1)*(x-2) div 6);
 6   end;
 7 
 8 function gcd(a,b:longint):longint;
 9   begin
10     if b=0 then exit(a)
11     else exit(gcd(b,a mod b));
12   end;
13 
14 begin
15   readln(n,m);
16   ans:=calc((n+1)*(m+1))-(n+1)*calc(m+1)-(m+1)*calc(n+1);
17   for i:=1 to n do
18     for j:=1 to m do
19     begin
20       tmp:=gcd(i,j)+1;
21       if tmp>2 then
22         ans:=ans-2*(n-i+1)*(m-j+1)*(tmp-2);
23     end;
24   writeln(ans);
25 end.
26 
27  
View Code

 

转载于:https://www.cnblogs.com/phile/p/4473112.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值