BZOJ3505: [Cqoi2014]数三角形

BZOJ3505: [Cqoi2014]数三角形

Description

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

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

Input

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

Output

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

Sample Input

2 2

Sample Output

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

题解Here!
此题不好直接求三角形个数,用补集转化思想转化为求三点共线的数量。

具体求法是先求出水平共线数量与竖直共线数量。

用排列组合的知识可知为$C_n^3$与$C_m^3$。

接着处理倾斜的直线。

直接枚举直线起点终点铁定$TLE$。

注意到除去水平与竖直直线后,每一条直线都是有斜率的。

故只需要枚举倾斜直线的倾斜向量,然后便可以使用最大公约数/排列组合的知识解决了。

附代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int gcd(int x,int y){
    if(y==0)return x;
    return gcd(y,x%y);
}
long long c(int n){
    long long s=1;
    s=s*(n-2)*(n-1)*n;
    s/=6;
    return s;
}
int main(){
    int n,m;
    long long ans;
    scanf("%d%d",&n,&m);
    n++;m++;
    ans=c(n*m);
    if(n>=3)ans-=c(n)*m;
    if(m>=3)ans-=c(m)*n;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++){
        long long s=gcd(i,j)-1;
        s=s*2*(n-i)*(m-j);
        ans-=s;
    }
    printf("%lld\n",ans);
    return 0;
}

 

posted @ 2018-08-20 10:33  符拉迪沃斯托克  阅读(197)  评论(0编辑  收藏  举报
Live2D