• [BZOJ3505][Cqoi2014]数三角形


    3505: [Cqoi2014]数三角形

    Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 1718  Solved: 1059 [Submit][Status][Discuss]

    Description

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

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

    Input

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

    Output

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

    Sample Input


    2 2

    Sample Output

    76


    数据范围
    1<=m,n<=1000
     
    显然格点为$left(n+1 ight)*left(m+1 ight)$个
    所以先$incleft(n ight),incleft(m ight)$
    考虑算出选三个点总数再减去共线情况
    总数$C_{n*m}^3$
    横竖共线$nC_m^3+mC_n^3$
    斜着的可以考虑枚举每两个点,然后计算两点连线上的格点
    考虑对于$left(0,0 ight)-left(x_0,y_0 ight)$的一条线段上
    所有点满足方程$y_0x-x_0y=0$,显然解有$gcd(x_0,y_0)+1$个
    排除掉两个端点还有$gcd(x_0,y_0)-1$个
    发现其实只要线段的$(dx,dy)$一样那么就是等价的而不用在意位置,所以乘一下就好了
    #include <iostream>
    typedef long long ll;
    inline ll gcd(ll a, ll b){
        ll t;
        if(a > b){
            t = a;
            a = b;
            b = t;
        }
        while(a){
            t = a;
            a = b % a;
            b = t;
        }
        return b;
    }
    ll n, m, ans;
    int main(){
        std::cin >> n >> m;
        n++;
        m++;
        ans = n * m * (n * m - 1) * (n * m - 2) - n * m * (m - 1) * (m - 2) - m * n * (n - 1) * (n - 2);
        ans /= 6;
        ll t;
        for(ll i = 1; i < n; i++)
            for(ll j = 1; j < m; j++){
                t = gcd(i, j);
                ans -= 2LL * (t - 1) * (n - i) * (m - j);
            }
        std::cout << ans << std::endl;
        return 0;
    }
  • 相关阅读:
    spring mvc 参数校验
    spring-boot 配置jsp
    java 多线程之取消与关闭
    spring transaction 初识
    java 读取环境变量和系统变量的方法
    每天一命令 git checkout
    每天一命令 git stash
    每天一命令 git reset
    log4j2配置详解
    专业名词及解释记录
  • 原文地址:https://www.cnblogs.com/ruoruoruo/p/7643174.html
Copyright © 2020-2023  润新知