HDU 1559 最大子矩阵(二维树状数组)

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

这是一道二维树状数组模板题。

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 1005;
typedef long long ll;
int m, n;
int c[MAXN][MAXN];
int lowbit(int x) {
	return x&(-x);
}
void add(int x, int y, int p) {  
    while(x <= n) {
        for(int i = y; i <= m; i += lowbit(i)) {
            c[x][i] += p;
        } 
        x += lowbit(x);
    }  
}  
ll sum(int x, int y) {  
    ll result = 0;  
    while(x > 0){
        for(int i = y; i > 0; i -= lowbit(i)) {
            result += c[x][i];
        }
        x -= lowbit(x);
    }  
    return result;  
}  
int main() {
	int t, a, b, q;
	cin>>t;
	while(t--) {
		memset(c, 0, sizeof(c));
		cin>>m>>n>>a>>b;
		for(int i = 1; i <= m; i++) {
			for(int j = 1; j <= n; j++) {
				cin>>q;
				add(i, j, q);
			}
		}
		ll mx = 0;
		for(int i = a; i <= m; i ++) {
			for(int j = b; j <= n; j++) {
				ll temp = sum(i, j) - sum(i - a, j) - sum(i, j - b) + sum(i - a, j- b);
				mx = max(mx, temp);
			}	
		}
		cout<<mx<<endl;
	}
	return 0;
}
扫描二维码关注公众号,回复: 2439745 查看本文章

猜你喜欢

转载自blog.csdn.net/adusts/article/details/81216302