• BZOJ 3505 数三角形


    Description

    给定一个nxm的网格,请计算三点都在格点上的三角形共有多少个。下图为4x4的网格上的一个三角形。

    注意三角形的三点不能共线。

    Input

    输入一行,包含两个空格分隔的正整数m和n。

    Output


    输出一个正整数,为所求三角形数量。

    Sample Input


    2 2

    Sample Output

    76


    数据范围
    1<=m,n<=1000

    如果不考虑三点共线的限制,那么方案数就是C(n*m,3) 然后来考虑不符合条件的数目


    如果是在同一行或同一列上好说,就是C(n,3)*m+C(m,3)*n


    那么在对角线上的呢? .. 用gcd搞一下,大致可理解为枚举每种矩形,然后再计算这种矩形


    内的对角线在整个棋盘中有多少种,再用Ans减去就好了

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <stdio.h>
    typedef long long ll;
    #define MAXN 1000005
    ll n,m,tot,C[MAXN][4],Ans;
     
     
    template<typename _t>
    inline _t read(){
        _t x=0,f=1;
        char ch=getchar();
        for(;ch>'9'||ch<'0';ch=getchar())if(ch=='-')f=-f;
        for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+(ch^48);
        return x*f;
    }
    inline ll gcd(ll x,ll y){return y==0?x:gcd(y,x%y);}
     
    void Get_C(){
        tot = n * m;
        C[0][0]=1;
        for(int i=1;i<=tot;i++){
            C[i][0]=1;
            for(int j=1;j<=3;j++)
                C[i][j]=C[i-1][j-1]+C[i-1][j];
        }
    }
     
    int main(){
        n=read<int>();m=read<int>();
        ++n;++m;Get_C();
        Ans += C[tot][3];Ans -= C[n][3] * m + C[m][3] * n;
        for(int i=1;i<n;i++)
            for(int j=1;j<m;j++){
                register ll kk = gcd(i,j);
                if(kk > 1)Ans -= 2*(kk-1)*(n-i)*(m-j);
            }
        printf("%lld
    ",Ans);
    }







  • 相关阅读:
    地铁开发进度1
    人月神话阅读笔记二
    学习进度五
    人月神话阅读笔记一
    WebView的用法:
    图框联动
    阅读笔记《人月神话》一
    5
    4
    3
  • 原文地址:https://www.cnblogs.com/Cooook/p/7738482.html
Copyright © 2020-2023  润新知