1. 程式人生 > >BZOJ3505 組合數學+整點計數

BZOJ3505 組合數學+整點計數

37 BZOJ3505 gcd+組合數學

題意:n*m的網格有多少個網格三角形 n,m<=1000

思路:總體減去三點共線的數目

三點共線:

水平,垂直都好算,打斜的怎麼算?(不一定是對角線!!)

這樣:列舉n,m作線段(0,n),(m,0)中間有gcd(m,n)-1個點可以選,

這條線有(n+1-i)*(m+1-j)種平移方案(向上向右)

//n*m的網格里有多少個三角形 n,m<1000; 
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll c3(ll x)
{
    if(x<3)return 0;
    return x*(x-1)*(x-2)/6;
}
int main()
{
    ll n,m;scanf("%lld%lld",&n,&m);
    if(n>m)swap(n,m);
    ll ans=c3((n+1)*(m+1));
    ans=ans-((n+1)*c3(m+1)+(m+1)*c3(n+1));
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            ans-=2*(__gcd(i,j)-1)*(n-i+1)*(m-j+1);
    printf("%lld\n",ans);   
}