zoukankan      html  css  js  c++  java
  • hdu-1559 最大子矩阵(二维树状数组模板题)

    最大子矩阵

    Time Limit: 30000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 5994    Accepted Submission(s): 3143


    Problem Description
    给你一个m×n的整数矩阵,在上面找一个x×y的子矩阵,使子矩阵中所有元素的和最大。
     

    Input
    输入数据的第一行为一个正整数T,表示有T组测试数据。每一组测试数据的第一行为四个正整数m,n,x,y(0<m,n<1000 AND 0<x<=m AND 0<y<=n),表示给定的矩形有m行n列。接下来这个矩阵,有m行,每行有n个不大于1000的正整数。
     

    Output
    对于每组数据,输出一个整数,表示子矩阵的最大和。
     

    Sample Input
    1 4 5 2 2 3 361 649 676 588 992 762 156 993 169 662 34 638 89 543 525 165 254 809 280
     

    Sample Output
    2474
     

    Author
    lwg
     

    Source
     

    Recommend
    LL
     
     
    根据数组[1, 2, 3, 4, 5]来创建对应的树状数组

    树状数组二叉索引树 其初衷是解决数据压缩里的累积频率的计算问题,现多用于高效计算数列的前缀和、区间和。

    它可以以O(log n)的时间得到任意前缀和

    {displaystyle sum _{i=1}^{j}a[i],1<=j<=N},并同时支持在{O(log n)时间内支持动态单点值的修改。空间复杂度O(n)

    #include <bits/stdc++.h>
    using namespace std;
    int map1[1005][1005];
    int m,n;
    inline int lowbit(int k)
    {
        return k&(-k);
    }
    void add(int x,int y,int vay)//更新(x,y)
    {
        for(int i=x; i<=m; i+=lowbit(i))
        {
            for(int j=y; j<=n; j+=lowbit(j))
            {
                map1[i][j]+=vay;
            }
        }
    }
    int sum(int x,int y)//求和
    {
        int s=0;
        for(int i=x; i>0; i-=lowbit(i))
        {
            for(int j=y; j>0; j-=lowbit(j))
            {
                s+=map1[i][j];
            }
        }
        return s;
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int tmp1,x,y,ans,res;
            scanf("%d %d %d %d",&m,&n,&x,&y);
            memset(map1,0,sizeof(map1));
            for(int i=1; i<=m; i++)
            {
                for(int j=1; j<=n; j++)
                {
                    scanf("%d",&tmp1);
                    add(i,j,tmp1);
                }
            }
            ans=0;
            res=0;
            for(int i=1; i<=m-x+1; i++)//注意+1
            {
                for(int j=1; j<=n-y+1; j++)
                {
                    res=sum(i+x-1,j+y-1)-sum(i-1,j+y-1)-sum(i+x-1,j-1)+sum(i-1,j-1);
                    ans=max(ans,res);
                }
            }
            cout<<ans<<'
    ';
        }
        return 0;
    }
    

      

  • 相关阅读:
    Objective-C中的锁及应用-13- 多线程
    Android开发技术周报 Issue#53
    Android开发技术周报 Issue#52
    Android开发技术周报 Issue#54
    Android开发技术周报 Issue#55
    Android开发技术周报 Issue#56
    Android开发技术周报 Issue#57
    Android开发技术周报 Issue#58
    Android开发技术周报 Issue#60
    Android开发技术周报 Issue#61
  • 原文地址:https://www.cnblogs.com/guanwen769aaaa/p/10350501.html
Copyright © 2011-2022 走看看