[CQOI2014]数三角形

给定\(n\times m\)的网格,求三个点在其格点上的三角形个数,1<=m,n<=1000。

法一:直接

显然为组合计数问题,关键在于划分问题,注意到一个三角形必然会被一个最小的矩形所限制,于是可以以矩形来划分,而现在问题变成对一个矩形内最大的三角形的方案数,显然最大三角形关键在于三角形顶点与矩形顶点之间的关系。

设有一\(a\times b\)矩形,有

1: 三角形有一个顶点在矩形顶点上,有4个矩形顶点可以选择,其余两个三角形顶点可以在剩余两条边自由移动,即\(4\times (a-1)\times (b-1)\)。

2:三角形有两个顶点在矩形同边顶点上,显然可以旋转4次,剩下一个三角顶点可以自由在一条边上移动,即\(2\times(a-1)+2\times(b-1)\)。

3:三角形有两个顶点在矩形对角顶点,此时该点能自由移动,只是不能在对角线上,


引理:对角线上的整点个数为gcd(a,b)+1

证明:

对于对角线上最靠近原点(0,0)的点(x,y),对角线上最靠近(x,y)的点必然是(2x,2y),依次类推,于是我们得知x,y必然是互质的,而取得gcd(a,b)即x,y前的系数,也就是除了原点之外的点,故加1及所需。


不难得知方案数应为\((a\times b-gcd(a,b)-1)\times 2\)

4:三角形有三个顶点在矩形对角顶点,显然讨论3已经包含了这种情况,故无需再考虑。

综上所诉,

\[ans=(n-a+1)\times(n-b+1)\times[4\times (a-1)\times (b-1)+
\]

\[2\times(a+b-2)+(a\times b-gcd(a,b)-1)\times 2]
\]

枚举计算答案即可。

参考代码:
#include <iostream>
#include <cstdio>
#define il inline
#define ri register
#define ll long long
using namespace std;
il int gcd(int,int);
int main(){
int m,n;
scanf("%d%d",&m,&n);
ri int i,j;ri ll ans(0);
for(i=1;i<=m;++i)
for(j=1;j<=n;++j)
ans+=(ll)(6*i*j-2*gcd(i,j))*(m+1-i)*(n+1-j);
printf("%lld",ans);
return 0;
}
il int gcd(int x,int y){
return x%y?gcd(y,x%y):y;
}

法二:补集

注意到直接做不好做,于是考虑补集,我们能很轻松求出不限制为三角形的方案数,于是我们考虑不是三角形的方案数,显然在一条直线上,于是考虑枚举直线,而这样我们没办法枚举唯一的斜率,这样会导致重复,于是考虑枚举线段,这样就确定了两个端点,另一个点必然在线段内,而方案数由法一的引理不难得出点数,再将该条线段平移加对称操作,枚举减总方案去即可,但是注意竖直和水平的直线,我们得额外减去其方案数。

所以

\[ans=C_{nm}^3-\sum_{i=1}^n\sum_{j=1}^m2\times (gcd(i,j)-1)\times (n-i+1)
\]

\[\times(m-j+1)-m\times C_n^3-n\times C_m^3
\]

参考代码:

#include <iostream>
#include <cstdio>
#define il inline
#define ri register
#define ll long long
#define swap(x,y) x^=y^=x^=y
using namespace std;
il int gcd(int,int);
int main(){
int n,m,i,j;ll ans;
scanf("%d%d",&n,&m),ans=(n+1)*(m+1);
ans*=(ans-1)*(ans-2),(ans/=3)/=2;
for(i=1;i<=n;++i)
for(j=1;j<=m;++j)
ans-=(gcd(i,j)-1)*(n-i+1)*(m-j+1)<<1;
ans-=(n+1)*n*(n-1)/3/2*(ll)(m+1),ans-=(m+1)*m*(m-1)/3/2*(ll)(n+1);
printf("%lld",ans);
return 0;
}
il int gcd(int a,int b){
while(b)swap(a,b),b%=a;return a;
}

[CQOI2014]数三角形的更多相关文章

  1. BZOJ 3505: [Cqoi2014]数三角形 数学

    3505: [Cqoi2014]数三角形 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

  2. Bzoj 3505: [Cqoi2014]数三角形 数论

    3505: [Cqoi2014]数三角形 Time Limits: 1000 ms  Memory Limits: 524288 KB  Detailed Limits   Description

  3. bzoj 3505: [Cqoi2014]数三角形 组合数学

    3505: [Cqoi2014]数三角形 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 478  Solved: 293[Submit][Status ...

  4. BZOJ 3505: [Cqoi2014]数三角形( 组合数 )

    先n++, m++ 显然答案就是C(3, n*m) - m*C(3, n) - n*C(3, m) - cnt. 表示在全部点中选出3个的方案减去不合法的, 同一行/列的不合法方案很好求, 对角线的不 ...

  5. 3505: [Cqoi2014]数三角形

    3505: [Cqoi2014]数三角形 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1324  Solved: 807[Submit][Statu ...

  6. BZOJ 3505: [Cqoi2014]数三角形 [组合计数]

    3505: [Cqoi2014]数三角形 给定一个nxm的网格,请计算三点都在格点上的三角形共有多少个. 注意三角形的三点不能共线. 1<=m,n<=1000 $n++ m++$ $ans ...

  7. bzoj3505 / P3166 [CQOI2014]数三角形

    P3166 [CQOI2014]数三角形 前置知识:某两个点$(x_{1},,y_{1}),(x_{2},y_{2})\quad (x_{1}<x_{2},y_{1}<y_{2})$所连成 ...

  8. BZOJ 3505 [Cqoi2014]数三角形

    3505: [Cqoi2014]数三角形 Description 给定一个nxm的网格,请计算三点都在格点上的三角形共有多少个.下图为4x4的网格上的一个三角形.注意三角形的三点不能共线. Input ...

  9. 【BZOJ3505】[Cqoi2014]数三角形 组合数

    [BZOJ3505][Cqoi2014]数三角形 Description 给定一个nxm的网格,请计算三点都在格点上的三角形共有多少个.下图为4x4的网格上的一个三角形. 注意三角形的三点不能共线. ...

随机推荐

  1. 微信小程序封装年月日时分组件

    第一步,在page下新建component文件,放你封装的小组件,和vue里的component差不多 第二步,在需要使用的组件的.json文件中添加usingComponents 第三步,在页面中引 ...

  2. lumen----------A facade root has not been set.

    1.新拉下来的lumen源码,直接使用Log::info是不行的.汇报如下图错误 解决办法如下图,因为lumen需要设置一些开关

  3. Java -- 基于JDK1.8的ArrayList源码分析

    1,前言 很久没有写博客了,很想念大家,18年都快过完了,才开始写第一篇,争取后面每周写点,权当是记录,因为最近在看JDK的Collection,而且ArrayList源码这一块也经常被面试官问道,所 ...

  4. window注册鼠标右键菜单,及子菜单

    最近项目中要用到c#并且要注册鼠标点击右键菜单,在这里总结了几种方法以便记录 效果图: 1,reg注册,创建.reg文件,内容如下 Windows Registry Editor Version 5. ...

  5. PHP获取汉字首字母函数

    <?php function getFirstCharter($str) { if (empty($str)) { return ''; } $fchar = ord($str{0}); if ...

  6. laravel application 容器app

    vendor/laravel/framework/src/Illuminate/Foundation/Application.php Application是laravel的核心容器,几乎处理所有东西 ...

  7. mac系统如何处理来自身份不明的开发者

    打开终端(终端在 应用程序 -> 实用工具 内) sudo spctl --master-disable

  8. Appium(一)---环境搭建的一些问题

    最近开始学习Appium,一款很不错的自动化测试工具,网上已经有大量的环境搭建教程,我就不再细说,我搭建环境时主要参考如下两个博客https://www.cnblogs.com/yoyoketang/ ...

  9. 基于Java服务的前后端分离解决跨域问题

    导语:解决跨域问题,前后端都增加相应的允许跨域的代码段即可. 一.后端增加允许跨域的代码,可以在具体controler层加,最好是在filter中添加,这样添加一次就够了,不用在每个controler ...

  10. PHP共享内存yac操作类

    http://www.laruence.com/2013/03/18/2846.html   鸟哥介绍 https://www.cnblogs.com/willamwang/p/8918377.htm ...