1. 程式人生 > 實用技巧 >棋盤

棋盤

Description

  給定一個n*n的棋盤,放置m顆棋子,一個位置是被攻擊的當且僅當這個存在某個棋子和這個位置是同行或者同列,你需要在每次放置一顆棋子過後,給出不被攻擊的位置數目。

Input

  第一行兩個整數n,m。
  接下來m行,每行兩個整數x,y表示放置的行和列。

Output

  每行輸出一個數表示當前不被攻擊的位置數目。

Sample Input

3 3
1 1
3 1
2 2

Sample Output

4
2
0

Hint

【資料範圍與約定】
  對於30%的資料,n≤100,m≤10000;
  對於50%的資料,n≤103,m<=105;
  對於100%的資料,n,m≤10^5。


思路

  • 討論新棋子的位置,1)同行同列都有攻擊,2)同行或同列有攻擊,3)同行同列都沒有攻擊
  • long long

程式碼

#include <iostream>
#include <cstdio>
#define maxn 100005
using namespace std;
int n,m,numh,numl;
bool h[maxn],l[maxn];
long long ans;
int main()
{
	scanf("%d%d",&n,&m); ans=(long long)n*n;
	while(m--)
	{
		int x,y; scanf("%d%d",&x,&y);
		if(h[x]&l[y]) ;
		else if(h[x]) ans-=(n-numl),++numh;
		else if(l[y]) ans-=(n-numh),++numl;
		else ans-=(2*n-numl-numh-1),++numh,++numl;
		h[x]=l[y]=1; printf("%lld\n",ans);
	}
	return 0;
}