您的位置:首页 > 其它

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

2016-01-21 16:39 381 查看
找规律就行了。。

首先所有的情况是C((n+1)*(m+1),3)。

水平+竖直共线的情况是(n+1)*C(m+1,3)+(m+1)*C(n+1,3).

剩下的就是斜着的情况:枚举i,j,代表两点为(1,i),(j,1)。然后令d=gcd(i,j),那么两点之间一定有d-1个点(所以要保证d>=2),那么现在不合法的情况有2*(d-1)(n+1-i)(m+1-j)。注意有两个方向所以要*2。

#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
int n,m;
ll ans;
ll c[1002005][4];
inline int read()
{
int a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}
inline void C()
{
c[0][0]=1;
for (int i=1;i<=(n+1)*(m+1);i++)
{
c[i][0]=1;
for (int j=1;j<=3;j++)
c[i][j]=c[i-1][j]+c[i-1][j-1];
}
}
int gcd(int a,int b)
{
return b==0?a:gcd(b,a%b);
}
int main()
{
n=read(); m=read();
C();
ans=c[(n+1)*(m+1)][3]-(n+1)*c[m+1][3]-(m+1)*c[n+1][3];
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
int d=gcd(i,j);
if (d>=2) ans-=2*(d-1)*(n+1-i)*(m+1-j);
}
cout << ans;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: