BZOJ 3505 [Cqoi2014]数三角形 - gcd

本文介绍了一种通过计算组合数并结合最大公约数(GCD)解决几何问题的方法。重点在于如何正确枚举矩形的顶点来避免重复计算,并考虑了平移产生的平行对角线。文中提供了一个C++实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

极其简单的一道题,求一下组合数再算一下gcd即可

一开始错是因为未考虑到除了(0,0)到(x,y)矩形平移还会产生平行的对角线。
后来乘上平移的数量,又发现只枚举矩形右下角的点并在对角线上采用组合数会出错,因为平移所乘的数和组合数会有大量重复,改成枚举矩形的左上和右下两个端点就好了,剩下一个点的数量即是对角线上点数-2。

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>

using namespace std;

int n,m;
long long c[4][1005];

void chart()
{
    c[0][0]=1;
    for(int i=1;i<=1002;i++)
    {
        c[0][i]=1;
        for(int j=1;j<=3;j++)
            c[j][i]=c[j-1][i-1]+c[j][i-1];
    }
}
int getgcd(int x,int y)
{
    if(!y)return x;
    return getgcd(y,x%y);
}
int main()
{
    scanf("%d%d",&n,&m);
    n++,m++;
    chart();
    int point=n*m;
    long long ans=1LL*point*(point-1)*(point-2)/6;
    ans-=1LL*m*c[3][n];
    ans-=1LL*n*c[3][m];
    for(int i=1;i<n;i++)
        for(int j=1;j<m;j++)
    {
        int gcd=getgcd(i,j);
        if(gcd>=2)
            ans-=1LL*(gcd-1)*2*(n-i)*(m-j);
    }
    printf("%lld",ans);
    return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值