数学专项counting:LA 3295
2013-09-18 22:59
423 查看
就是分类统计,分3类。第一种是一条水平的或竖直的边,数目为所有对角线条数的两倍;第二种是有一条水平的边和一条竖直的边,数目为所有对角线条数的(2*n+2*m-4)倍;第三类是3条边均不是水平或竖直的,先从n+1条水平边中任取3条,即C(n+1,3),再在m+1条竖直边取3条边的排列,即P(m+1,3),利用乘法原则,总数为C(n+1,3)* P(m+1,3),但此处多算了3点共线的情况,只要在计算对角线的时候,将相应的对角线条数时乘上其长宽的gcd-1即可(即该对角线除去端点后经过的格点数),最后将其减去即可。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; typedef long long LL; const int maxn=1010; int g[maxn][maxn]; int gcd(int a,int b){return b==0?a:gcd(b,a%b);} void init() { for(int i=1;i<=1000;i++) for(int j=i;j<=1000;j++) g[i][j]=g[j][i]=gcd(i,j); } int main() { init(); int n,m; int kase=1; while(~scanf("%d%d",&n,&m)) { if(!n && !m) break; LL dig=0,tmp=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { dig+=(n-i+1)*(m-j+1); tmp+=(n-i+1)*(m-j+1)*(g[i][j]-1); } dig*=2;tmp*=2; LL ans=dig*(2*n+2*m-4)/2+dig*2-tmp; ans+=(LL)(n+1)*n*(n-1)*(m+1)*m*(m-1)/6; printf("Case %d: %lld\n",kase++,ans); } return 0; }
相关文章推荐
- 数学专项counting:LA 3357
- 数学专项counting:LA 4064
- 数学专项counting:LA 3720
- 数学专项counting:LA 5846
- 数学专项counting:UVa 10128
- 数学专项counting:UVa 11038
- 数学专项number_theory:LA 3262
- 数学专项counting:UVa 10883
- 数学专项number_theory:LA 4382
- 数学专项counting:UVa 11529
- 数学专项counting:UVa 10079
- 数学专项counting:UVa 10081
- 数学专项number_theory:LA 4079
- 数学专项number_theory:LA 2955
- 数学专项matrix:LA 2561
- 数学专项counting:UVa 580
- 数学专项counting:UVa 417
- 数学专项counting:UVa 11481
- 数学专项counting:UVa 10237
- 杂题专项:LA 5842