Luogu P3166 [CQOI2014]数三角形 组合数学

Posted jackpei

tags:

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

好题鸭。。

不好直接求三角形个数,那就用全集-补集,转化为求三点共线的数量。

具体求法是求出水平共线数量与竖直共线数量和斜线共线数量。

用排列组合的知识可知为水平和竖直的为$C_n^3$?与$C_m^3?$。

求斜线三点共线:显然,对于点$(a,b) (x,y)$连成的线段$(其中a>x,b>y)$,在它们中间有$gcd(a-x,b-y)-1$个整点,因此基本的思路就是枚举两个点,然后第3个点就是$gcd(a-x,b-y)-1$种可能了。我们又发现,这些线段是可以平移和对称(/和\)的,于是并不需要枚举所有的两个点,只用枚举$(0,0)$和$(x,y)$,然后通过平移和对称($*2$)来计算出现的次数。

那么可以发现,这样任意一条线,向上只能平移$(n-i)$,向下$(m - j)$次,

所以出现次数就为$(n - i + 1) * (m - j + 1)$,其中$+1$是因为可以不移动

#include<iostream>
#include<cstdio>
#define ll long long
#define R register ll
using namespace std;
inline int g() 
    R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch==-?-1:fix;
    do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;

int n,m;
ll ans;
inline int gcd(int a,int b) return b?gcd(b,a%b):a;
signed main() 
    n=g()+1,m=g()+1; ans=1ll*n*m;
    ans=1ll*ans*(ans-1)*(ans-2)/6-1ll*m*n*(n-1)*(n-2)/6-1ll*n*m*(m-1)*(m-2)/6;
    for(R i=1;i<n;++i) for(R j=1;j<m;++j) ans-=1ll*2*(gcd(i,j)-1)*(n-i)*(m-j);
    printf("%lld\n",ans);

2019.06.01

 

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

bzoj3505 / P3166 [CQOI2014]数三角形

洛谷P3166 [CQOI2014]数三角形

P3166 [CQOI2014]数三角形

题解 P3166 [CQOI2014]数三角形

BZOJ3505[Cqoi2014]数三角形 组合数

3505: [Cqoi2014]数三角形