zoukankan      html  css  js  c++  java
  • [Cqoi2014]数三角形——组合数

    Description:

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

    注意三角形的三点不能共线。

    Hint:

    1<=m,n<=1000

    Solution:

    直接算三角形肯定算死。

    所以,先考虑所有的可能三角形。再减去不合法的三点共线的情况。

    所有三角形:C((n+1)*(m+1),3)

    不合法的情况怎么处理??

    开始的想法:

    1.找所有的两端在坐标轴上的直线,算出来整点数:gcd(x,y)+1;再算上下,左右的直线。

    但是发现可能有的不合法直线不过边框的整点!!bug

    2.考虑直线的方程:ax+by+c=0

    a,b,c是常整数。并且都在1~n(m)的范围内。

    相当于求x,y的非负整数解的个数。(exgcd)

    但是待定系数n^4,枚举系数n^3都不行。bug

    正解:

    优化一下

    发现找直线非常复杂。

    如果我们找线段呢?并且保证线段的两端都在整点上?相当于把直线根据整点拆开了

    (a,b)(c,d)的线段中间的整点有gcd(abs(c-a),abs(d-b))-1个方案。

    枚举线段减去中间放点的方案,这样还是n^4

    发现,许多的线段本质上是一致的,只是平移了。

    所以,我们只需要枚举所有的(0,0)(x,y),就可以了、。

    平移的方案就是(n+1-x)*(m+1-y)相当于画出了一个矩形。

    对于不是在坐标轴上的点,我们还要乘2,相当于上下一个对称情况。

    Code:

    #include<cstdio>
    #define LL long long
    int gcd[1010][1010];
    int n,m;
    LL t,ans;
    inline int getgcd(int a,int b)
    {
        if (gcd[a][b])return gcd[a][b];
        if (!a)return gcd[a][b]=b;
        if (!b)return gcd[a][b]=a;
        return gcd[a][b]=getgcd(b,a%b);
    }
    inline void calc()
    {
        for(int i=1;i<=m;i++)gcd[0][i]=i;
        for(int i=1;i<=n;i++)gcd[i][0]=i;
        for(int i=1;i<=n;i++)
          for(int j=1;j<=m;j++)
            getgcd(i,j);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        calc();
        t=(n+1)*(m+1);
        ans=t*(t-1)*(t-2)/6;
        for (int i=0;i<=n;i++)
          for (int j=0;j<=m;j++)
            if (i||j)
            {
                if (!i||!j)ans-=(LL)(gcd[i][j]-1)*(n-i+1)*(m-j+1);
                else ans-=(LL)2*(gcd[i][j]-1)*(n-i+1)*(m-j+1);
            }
        printf("%lld",ans);
    }
  • 相关阅读:
    350. Intersection of Two Arrays II
    94. Binary Tree Inorder Traversal
    623. Add One Row to Tree
    JS判断是否为数字,中文,小写、大写字母
    ASP.NET 操作Cookie详解 增加,修改,删除
    ASP.NET MVC 入门1、简介
    通过LINQ TO SQL类显示数据库表的数据
    OutputCache缓存优化asp.net代码 提高网页性能
    数据库读取二进制图片显示到PictureBox中
    WinForm窗体间如何传值的几种方法
  • 原文地址:https://www.cnblogs.com/Miracevin/p/9400674.html
Copyright © 2011-2022 走看看