【Ukraine】Bishops(棋盘上点的四个方向标记黑块,求最后白块数)

给出一个n*n的棋盘和k个点,再给出这k个点的坐标,每个点的斜对角四个方向所有位置都记标成黑块,求最后棋盘上还剩下多少白块?

In chess, a bishop is a piece, which attacks all fields of the chessboard, which are placed at same diagonal with it (in both diagonal directions).

 【Ukraine】Bishops(棋盘上点的四个方向标记黑块,求最后白块数)_第1张图片

On the chessboard N N Stefan placed M bishops. Now he wants to calculate number of fields, which are not attacked by any bishop.

Help Stefan to do it.


Input

First line of the input contains two integers N (1 N 106) and M (1 M 105) dimension of the chessboard and number of bishops, respectively. Then M lines follow. Each of those M lines contains two space-separated integers ri and ci 1-based numbers of row and column for i’th bishop (1 ri; ci N). No two bishops share the same field.

 

Output

Print one integer   number of fields, which are not attacked by a bishop.

 

Example

standard input

standard output

10 6

33

4 7

 

8 5

 

8 7

 

6 2

 

9 7

 

8 4


#include <bits/stdc++.h> 
using namespace std;
const int N = 1e6 + 5;
int n,k;
bitset< N<<1 > c,r; 
int nc[N], nr[N];
int main() {
		scanf("%d%d", &n, &k);
	//	c.reset(); r.reset();
		while(k--){
			int x, y;
			scanf("%d%d", &x, &y);
			x--; y--;
			r[x+y] = 1;
			c[x+(n-1-y)] = 1;
		}
		long long ans = 0, sum[] = {0, 0};
		for(int i = 0; i<n-1; i++) {
			nc[i] = c[i] + c[2*n-2-i]; //求长度为i+1的左斜段的个数 
			nr[i] = r[i] + r[2*n-2-i]; //求长度为i+1的右斜段的个数 
			ans += 1LL*(nc[i] + nr[i])*(i+1); //不考虑去重时黑格子个数 
		}
		nc[n-1] = c[n-1]; //i=2*n-2-i ,算出i=n-1,只能计算一次,所以拎出来 
		nr[n-1] = r[n-1];
		ans += (nc[n-1]+nr[n-1])*n;
		//以右斜线为例,长度越长能交到的左斜线越多(有点贪心思想)
		//长度为1的右斜线只能交到长度为n的
		//长度为2的右斜线只能交到长度为n-1的
		//长度为3的右斜线只能交到长度为n和n-2的
		//长度为4的右斜线只能交到长度为n-1和n-3的
		//......
		//累加操作即可。以i&1分开累加当前符合的左斜线个数,再乘上当前长度的右斜线个数。 
		for(int i = 0; i<n; i++) {
			sum[i&1] += nr[n-1-i];
			ans -= sum[i&1]*nc[i];
		}
		printf("%lld\n", 1LL*n*n-ans);
	return 0;
}

另外还有一种树状数组的做法。

有时候情况考虑多也很可怕。所以还是要仔细审题,想想是不是充分利用到了题目的条件来简化问题,不要读了两句就开始磨刀霍霍。。。


你可能感兴趣的:(【Ukraine】Bishops(棋盘上点的四个方向标记黑块,求最后白块数))