[bzoj3505][數論]數三角形
阿新 • • 發佈:2018-12-12
Description
給定一個nxm的網格,請計算三點都在格點上的三角形共有多少個。下圖為4x4的網格上的一個三角形。
注意三角形的三點不能共線。
Input
輸入一行,包含兩個空格分隔的正整數m和n。
Output
輸出一個正整數,為所求三角形數量。
Sample Input
2 2
Sample Output
76
HINT
資料範圍
1<=m,n<=1000
題解
有點妙啊… 先n++,m++ 想到了尋找三點共線的方案但是隻會… 首先橫豎兩種方案可以很容易去掉 只考慮斜著的線段 列舉以這條邊為對角線的矩陣邊長i,j 那麼這條線段內會經過個整點 那麼這條邊,實際上是可以平移的 一共可以平移次 固定了兩端的點 在中間選點共有種方案 一條線段的貢獻就是
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<vector> #include<ctime> #define LL long long #define mp(x,y) make_pair(x,y) using namespace std; inline int read() { int f=1,x=0;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } inline void write(int x) { if(x<0)putchar('-'),x=-x; if(x>9)write(x/10); putchar(x%10+'0'); } inline void print(int x){write(x);printf(" ");} LL C(LL n) { if(n<3)return 0; return n*(n-1)*(n-2)/6; } LL gcd(LL a,LL b){return a==0?b:gcd(b%a,a);} LL n,m; int main() { n=read();m=read();n++;m++; LL ans=C(n*m)-n*C(m)-m*C(n); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) ans-=2*(gcd(i,j)-1)*(n-i)*(m-j); printf("%lld\n",ans); return 0; }