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