数学专项counting:LA 3295

来源:互联网 发布:手机知乎怎么上传图片 编辑:程序博客网 时间:2024/05/21 11:00

就是分类统计,分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;}


原创粉丝点击