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
",ans);
}
return 0;
}