[Cqoi2014]数三角形——组合数

[Cqoi2014]数三角形——组合数[Cqoi2014]数三角形——组合数

大家好,又见面了,我是你们的朋友全栈君。

Description:

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

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

Hint:

1<=m,n<=1000

Solution:

直接算三角形肯定算死。

所以,先考虑所有的可能三角形。再减去不合法的三点共线的情况。

所有三角形:C((n+1)*(m+1),3)

不合法的情况怎么处理??

 

开始的想法:

1.找所有的两端在坐标轴上的直线,算出来整点数:gcd(x,y)+1;再算上下,左右的直线。

但是发现可能有的不合法直线不过边框的整点!!bug

2.考虑直线的方程:ax+by+c=0

a,b,c是常整数。并且都在1~n(m)的范围内。

相当于求x,y的非负整数解的个数。(exgcd)

但是待定系数n^4,枚举系数n^3都不行。bug

 

正解:

优化一下

发现找直线非常复杂。

如果我们找线段呢?并且保证线段的两端都在整点上?相当于把直线根据整点拆开了

(a,b)(c,d)的线段中间的整点有gcd(abs(c-a),abs(d-b))-1个方案。

枚举线段减去中间放点的方案,这样还是n^4

发现,许多的线段本质上是一致的,只是平移了。

所以,我们只需要枚举所有的(0,0)(x,y),就可以了、。

平移的方案就是(n+1-x)*(m+1-y)相当于画出了一个矩形。

对于不是在坐标轴上的点,我们还要乘2,相当于上下一个对称情况。

Code:

#include<cstdio>
#define LL long long
int gcd[1010][1010];
int n,m;
LL t,ans;
inline 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);
}
inline void calc()
{
    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);
}
int main()
{
    scanf("%d%d",&n,&m);
    calc();
    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-=(LL)(gcd[i][j]-1)*(n-i+1)*(m-j+1);
            else ans-=(LL)2*(gcd[i][j]-1)*(n-i+1)*(m-j+1);
        }
    printf("%lld",ans);
}

 

转载于:https://www.cnblogs.com/Miracevin/p/9400674.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/107389.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • log4j 配置日志输出(log4j.properties)

    log4j 配置日志输出(log4j.properties)2018年5月27日一、入门log4j实例1.1下载解压log4j.jar

    2022年7月15日
    16
  • Word在试图打开文件时遇到错误。解决办法!

    Word在试图打开文件时遇到错误。解决办法!下载Word文档,看看“软考网络工程师”的试题!但是文档打不开,显示如图二图一图二解决步骤:看到这报错,第一感觉,是不是OFFICE本身的问题?除了这个下载的文档不能打开,其它的WORD文档一般都能用WORD打开!晕死。。。先在微软官方网站下载Office2003SP3-KB923618-FullFile-CHS.exe,修复一下O…

    2022年5月1日
    61
  • 红旗 Linux 官方社区_红旗车机系统3.0

    红旗 Linux 官方社区_红旗车机系统3.0红旗inWise操作系统V8.0英文名是RedFlaginWiseV8.0,曾经让很多国内Linux用户所应用的国产操作系统,该版本是对系统软件包组件的升级和稳定性易用性的整体提升。对于老电脑的来说,安装该版本是一个可取的决定,现在提供红旗inWise操作系统V8.0的下载。RedFlaginWiseV8.0主要新特性1、最新的稳定内核3.6.11和各种驱动程序包,使系统具备更好的硬件…

    2022年8月20日
    16
  • 参加persist.sys物业写权限的方法

    参加persist.sys物业写权限的方法

    2022年1月12日
    68
  • navicat15永久激活码最新【中文破解版】[通俗易懂]

    (navicat15永久激活码最新)本文适用于JetBrains家族所有ide,包括IntelliJidea,phpstorm,webstorm,pycharm,datagrip等。https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~V…

    2022年3月22日
    93
  • python发邮件详解,smtplib和email模块详解

    python发邮件详解,smtplib和email模块详解在介绍具体的实现python发邮件的具体操作之前,我觉得有必要介绍下SMTP,更有助于理解python发邮件的实现原理。SMTP协议属于TCP/IP协议簇,即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式,python实现发邮件也是基于此基础上进行封装的。1.python发邮件所需要的基础包python发送邮件需要用到python自带的两个模块,s…

    2025年8月7日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号