1. 程式人生 > >[bzoj3505 Cqoi2014] 數三角形 (容斥+數學)

[bzoj3505 Cqoi2014] 數三角形 (容斥+數學)

print return NPU 數量 lse 三個點 sin string namespace

傳送門

Description

給定一個nxm的網格,請計算三點都在格點上的三角形共有多少個。下圖為4x4的網格上的一個三角形。

註意三角形的三點不能共線。

Input

輸入一行,包含兩個空格分隔的正整數m和n。

Output

輸出一個正整數,為所求三角形數量。

Sample Input

2 2

Sample Output

76

HINT

1<=m,n<=1000

Solution

首先思路肯定是隨意三個點方案-三點共線方案
隨意三個點方案隨意求
主要求三點共線:
有個神奇的結論:節點坐標gcd-1 是矩形內的點個數 也就是這個矩形確定兩端點的方案數
只要枚舉一個矩形大小然後平移什麽的就行了

PS:註意特殊情況

Code

//By Menteur_Hxy
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;

LL gcd(LL a,LL b) {return !b?a:gcd(b,a%b);}

int main() {
    LL n,m,t,ans;
    scanf("%lld %lld",&n,&m);
    t=(n+1)*(m+1);
    ans=t*(t-1)*(t-2)/6;
    for(int i=0;i<=n;i++) 
        for(int j=0;j<=m;j++) {
            t=(gcd(i,j)-1);
            if(t<=0) continue;
            t*=(n-i+1)*(m-j+1);
            if(i&&j) ans-=t<<1;
            else ans-=t;//"特殊情況"
        }
    printf("%lld",ans);
    return 0;
}

[bzoj3505 Cqoi2014] 數三角形 (容斥+數學)