每日一題 — 2020 - 04 - 19

題目鏈接

可以看出是差分和前綴和(差分的話自己並不熟練),這題主要是對前面知識進行回顧了差分和前綴和的知識。


解題思路:

  • 首先這個先利用差分來記錄每個點的值,這裏利用差分,然後類似於前綴和的形式來求出每個位置的值
  • 然後我們利用前綴和(二維前綴和)
  • 然後最終求出即可

這裏需要注意的是:(注意形式)

二維前綴和:

a[i][j] = a[i][j] + a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1];

求出結果:

a[x2][y2] - a[x1 - 1][y2] - a[x2][y1 - 1] + a[x1 - 1][y1 - 1];


代碼:

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

long long a[2010][2010];

int main(){
	int n, m, k, q;
	scanf("%d%d%d%d",&n,&m,&k,&q);
	for (int i = 0; i < k; i ++){
		int x1, y1, x2, y2;
		scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
		a[x1][y1] += 1;
		a[x2 + 1][y1] -= 1;
		a[x1][y2 + 1] -= 1;
		a[x2 + 1][y2 + 1] += 1;
	}
	
	// 差分完每一塊的值
	for (int i = 1; i <= n; i++){
		for (int j = 1; j <= m; j ++){
			a[i][j] = a[i][j] + a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1];
		}
	}

	// 前綴和
	for (int i = 1; i <= n; i++){
		for (int j = 1; j <= m; j ++){
			a[i][j] = a[i][j] + a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1];
		}
	}

	for (int i  = 0 ; i < q; i ++){
		int x1, y1, x2, y2;
		scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
		printf("%lld\n",a[x2][y2] - a[x1 - 1][y2] - a[x2][y1 - 1] + a[x1 - 1][y1 - 1]);
	}
	return 0;

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章