• bzoj3505[CQOI2014]数三角形


    题意:给你一张n*m(n,m<=1000)的网格图,问有多少个顶点在格点上的三角形(共线不算).

    首先补集转化,不考虑共线的方案是C(n*m,3),减去共线方案数即可.

    对于共线方案数的统计,首先可以考虑O(n^4)暴力枚举两个端点(x1,y1)(x2,y2),中间的点有gcd(x2-x1,y2-y1)-1个.然后发现可以只O(n^2)枚举(x2-x1)和(y2-y1)的值,数一数对应的情况有多少个,相当于在网格图内平移一个长(x2-x1)宽(y2-y1)的矩形,能摆在多少个不同的位置,那么就是(n-(x2-x1)+1)*(m-(y2-y1)+1)种.

    我写了一发DP,略有不同,不过思想是相通的。

    记f[i][j]为点(i,j)为左上角时的重复方案数,包括斜向的和水平垂直的.例如f[1][1]=0,f[1][2]=0,f[1][3]=1,f[2][2]=0,f[3][3]=3

    (题目里给的n,m是“长度”,也就是说输入n时一条边有n+1个点,我这里状态定义的坐标略有不同,f[1][1]是一个孤立的点,f[2][2]是四个点组成的正方形)

      (这是f[3][3]=3)

    转移的时候,考虑从f[i-1][j]转移到f[i][j].

    实际上,可以认为f[i][j]是在f[i-1][j]的图形右侧加了一列,左上角没有动

    (从f[3][3]变到f[4][3],可以看到增加了图中点(1,2,4)(1,3,4)的共线情况)

    一个结论:点(i,j)和点(i+dx,j+dy)的连线上除了端点,有gcd(dx,dy)-1个整点. 因为每次是增加整整一列,暴力转移是O(n^3)的.但是一起考虑i相同的所有状态,会发现它们转移时有大量重复计算。

    例如:f[4][3]=f[3][3]+[gcd(3,0)-1]+[gcd(3,1)-1]+[gcd(3,2)-1]

            f[4][4]=f[3][4]+[gcd(3,0)-1]+[gcd(3,1)-1]+[gcd(3,2)-1]+[gcd(3,3)-1]因此可以记录后边那个gcd-1的和,每个状态的转移是O(1)的. 注意这里只算了向右下方倾斜的,但向左向右倾斜都可以,所以根据对称要乘2.处理向左/向右倾斜的时候我把水平和垂直的情况算了两次,最后还要单独处理一下.

    (f数组可以不用long long. N^2对数的gcd可以用辗转相减递推预处理)

    #include<cstdio>
    typedef long long ll;
    const int maxn=1005;
    int g[maxn][maxn],f[maxn][maxn];
    ll m,n;
    void init(){
        for(int i=0;i<maxn;++i)g[i][i]=g[i][0]=g[0][i]=i;
        for(int i=1;i<maxn;++i){
            for(int j=1;j<=i;++j){
                g[j][i]=g[i][j]=g[j][i-j];
            }
        }
    }
    int main(){
        scanf("%lld%lld",&m,&n);m++;n++;
        init();
        ll ans=(m*n)*(m*n-1)*(m*n-2)/6;
        for(int i=1;i<=n;++i){
            int tmp=0;
            for(int j=1;j<=m;++j){
                //blablabla
                if(g[j-1][i-1])tmp+=g[j-1][i-1]-1;
                f[i][j]=f[i-1][j]+tmp;
                ans-=f[i][j]*2;
            }
        }    
        if(n>=3)ans+=m*(n)*(n-1)*(n-2)/6;
        if(m>=3)ans+=n*(m)*(m-1)*(m-2)/6;
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    L3-028 森森旅游 题解(最短路)
    Codeforces Round #717 (Div. 2) 题解(A-D)
    大爽Python入门教程 总目录
    Django笔记&教程 2-4 视图常用
    python一对一教程:Computational Problems for Physics chapter 1-B Code Listings 1.7
    python一对一教程:Computational Problems for Physics chapter 1 Code Listings
    b站个人直播年报【大爽歌作】 介绍与演示
    架构漫谈阅读笔记03
    架构漫谈阅读笔记02
    架构漫谈阅读笔记01
  • 原文地址:https://www.cnblogs.com/liu-runda/p/5993244.html
Copyright © 2020-2023  润新知