[计数][CQOI2014]数三角形

Posted yuxiaoze

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[计数][CQOI2014]数三角形相关的知识,希望对你有一定的参考价值。

题目描述

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

输入格式

输入一行,包含两个空格分隔的正整数m和n。

输出格式

输出一个正整数,为所求三角形数量。

输入输出样例

输入 #1
2 2
输出 #1
76

说明/提示

数据范围 1<=m,n<=1000

 

题解

首先,选三个点的方案是C((n+1)*(m+1),3)

然后减去三点共线的方案数即可

在一行共线的方案数为C(n+1,3)*(m+1)//m+1列

在一列共线的方案数为C(m+1,3)*(n+1)//n+1行

考虑在一条斜线上共线

假设左下方的点到右上方的点的向量为(i,j)

那么,他中间有gcd(i,j)-1个格点

而在(n+1)*(m+1)的图里可以放(n+1-i)*(m+1-j)个这样的向量

而它也有可能是从坐上到右下,方案数一模一样

所以要求的就是∑(i=1)(n)∑(j=1)(m)[ (n+1-i)*(m+1-j)*(gcd(i,j)-1)*2]

 

为什么我会如此zz地枚举斜线的斜率。。。枚举两个点找第三个点就好了。。。我整个人都傻了

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 long long n,m;
 5 inline long long C(long long x) if(x<3) return 0;return x*(x-1)*(x-2)/6;
 6 inline long long gcd(long long x,long long y) if(y==0) return x; return gcd(y,x%y);
 7 int main()
 8  
 9   scanf("%lld%lld",&n,&m); long long ans=C((n+1)*(m+1))-(m+1)*C(n+1)-(n+1)*C(m+1);
10 
11   for(long long i=1;i<=n;i++)
12    for(long long j=1;j<=m;j++)
13         ans-=(n+1-i)*(m+1-j)*(gcd(i,j)-1)*2;
14 
15 
16   printf("%lld",ans);
17  return 0;
18  

 

 

以上是关于[计数][CQOI2014]数三角形的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ3505[Cqoi2014]数三角形 组合数

BZOJ 3505 [Cqoi2014]数三角形

bzoj3505 [Cqoi2014]数三角形

P3166 [CQOI2014]数三角形(组合数学)

[CQOI2014]数三角形

BZOJ-3505: [Cqoi2014]数三角形 (容斥原理+排列组合)