网格中数三角形

7 篇文章 0 订阅

``[网易2019算法] 网格中数三角形 题解
参考链接:https://zybuluo.com/Junlier/note/1328780
链接题目地址:洛谷P3166 BZOJ 3505

首先证明一个几何结论:给定两个整点(x1,y1),(x2,y2),求这段线段之间跨过的整点的个数为
num=gcd(x1−x2,y1−y2)
证明:
  令 x=x1−x2,y=y1−y2
  令 d=gcd(x,y)
  x=pd,y=qd
  令直线上某一点为(a,h), 不妨设x1=y1=0
  由相似三角形可得:
  ax=hy
  a=hx/y=hpd/qd=hp/q ,p与q互质。
  那么ans也就是对于1<=h<=y来说,有多少个a是整数了。
  显然,a的最大值为x,最小值为p。
  设x = pn
  y = qn
  ans = n = gcd(x,y), 证毕。
  
在本题中,不考虑两端的点,故num=gcd(x1−x2,y1−y2)-1,方块网格有n行、m列
**基本思路:**所有点中取出三个点的组合数,减去三点共线的数目;三点共线分为直的和斜的。

  1. 三点共线的直线平行于或轴:那很简单直接组合数减掉和
  2. 三点共线的直线是个斜的
    首先想一个做法
    考虑枚举三个点两端的两个点(为了不算重所以枚举两端的点)
    显然以这两个点为两端的共线方案数就是这条线中间经过的整点数 、
    我们发现其实很多直线其实长得是一样的,只是放的位置不一样而已
    我们考虑把这些长得一样的直线一起处理
    那我们直接把当做原点,枚举 (x,y)
    会发现其实那些和他长得一样的直线相当于是在这种情况下于坐标网格中有限制地移动
    那么计算出它可以移动的方案数:
    这个很容易算,不就是往上移动不过(n-x)次,往右移动(m-y)次
    那么具体算出来就是(n-x)*(m-y)次了,再乘上gcd(x,y)-1就是要减去的(当然只枚举了,斜率是正的,斜率是负的就只要反过来吗,于是我们×2)

代码如下:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define int long long
#define IN inline
int n,m,t,ans,gcd[1010][1010];
IN int getgcd(int a,int b){
    if(gcd[a][b]) return gcd[a][b];
    if(!a) return gcd[a][b]=b;
    if(!b) return gcd[a][b]=a;
    return gcd[a][b]=getgcd(b,a%b);
}
IN void init(){
    for(int i=1;i<=m;i++) gcd[0][i]=i;
    for(int i=1;i<=n;i++) gcd[i][0]=i;
    for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) getgcd(i,j);
}
signed main(){
    scanf("%lld%lld",&n,&m);
    init();
    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++)
            if(i||j){
                if(!i||!j) ans-=(gcd[i][j]-1)*(n-i+1)*(m-j+1);
                else ans-=2*(gcd[i][j]-1)*(n-i+1)*(m-j+1);
            }
    printf("%lld",ans);
}插入代码片
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值