填坑……链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3505
题意:给出一个矩形,任取三点,问不共线情况多少种。
首先我们利用补集转化,将这个问题转化为所有方案减去贡献情况。第一个显然是一个普通的组合数计算,关键在于后一半怎么计算。
看下面一个例子:
从$(0,0)$向$(2,4)$连了一条线,$gcd(2,4)=2$,然后这条线段中间有一个点。
实际上我们可以用函数解释。把这条线看做函数,我每走一个$(x/gcd(x,y),y/gcd(x,y))$都会经过一个整点,当我走到$(x,y)$时就走了$gcd(x,y)$个整点,再去掉终点就是结果。
然后,我们就可以寻找各种由同一直线平移或者旋转$180°$得到的直线,同时加上这些点的数量再计算即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 int n,m; 7 int gcd(int x,int y) 8 { 9 return (!y)?x:gcd(y,x%y); 10 } 11 int haha() 12 { 13 scanf("%d%d",&n,&m);long long cnt=(n+1)*(m+1); 14 long long num=cnt*(cnt-1)*(cnt-2)/6; 15 for(int i=0;i<=m;i++) 16 for(int j=0;j<=n;j++) 17 if(i||j) 18 { 19 long long t=1ll*(gcd(i,j)-1)*(m+1-i)*(n+1-j); 20 if(!i||!j)num-=t;else num-=2*t; 21 } 22 printf("%lld ",num); 23 } 24 int sb=haha(); 25 int main(){;}