点击打开题目
B. Cells Not Under Attack
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Vasya has the square chessboard of size n × n and m rooks. Initially the chessboard is empty. Vasya will consequently put the rooks on the board one after another.
The cell of the field is under rook's attack, if there is at least one rook located in the same row or in the same column with this cell. If there is a rook located in the cell, this cell is also under attack.
You are given the positions of the board where Vasya will put rooks. For each rook you have to determine the number of cells which arenot under attack after Vasya puts it on the board.
Input
The first line of the input contains two integers n and m (1 ≤ n ≤ 100 000, 1 ≤ m ≤ min(100 000, n2)) — the size of the board and the number of rooks.
Each of the next m lines contains integers xi and yi (1 ≤ xi, yi ≤ n) — the number of the row and the number of the column where Vasya will put the i-th rook. Vasya puts rooks on the board in the order they appear in the input. It is guaranteed that any cell will contain no more than one rook.
Output
Print m integer, the i-th of them should be equal to the number of cells that are not under attack after first i rooks are put.
Examples
input
3 3
1 1
3 1
2 2output
4 2 0 input
5 2
1 5
5 1output
16 9 input
100000 1
300 400output
9999800001 Note
On the picture below show the state of the board after put each of the three rooks. The cells which painted with grey color is not under the attack.

这道题应该想办法转化一下。
如果放上一个棋子,而这个格子还没有受到攻击,那么它将影响一行和一列,我们不管这一行一列能和其他的有多少冲突,我们就把没有被攻击的点都移动到右下角聚集起来,就像上图最左边的一样。最左边的图的结果和在(2,2)位置上放一个棋子的结果是相等的。然后我们就发现,我们要计算的结果就是一个矩形的面积。
那么还有一种情况,就是这个棋子所在的行或者列已经可以被攻击了,那么也很简单,这一行或者列不计算即可。
代码如下:
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
#define CLR(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
bool w[100000+11]; //x、y被影响的格子数
bool h[100000+11];
int nx,ny;
int main()
{
int n,k;
while (~scanf ("%d %d",&n,&k))
{
CLR(w,false);
CLR(h,false);
queue<__int64> q; //队列存结果
nx = ny = 0;
while (k--)
{
int x,y;
scanf ("%d %d",&x,&y);
if (!h[x])
{
h[x] = true;
nx++;
}
if (!w[y])
{
w[y] = true;
ny++;
}
q.push((__int64)(n-nx) * (n-ny));
}
while (q.size() != 1)
{
printf ("%I64d ",q.front());
q.pop();
}
printf ("%I64d\n",q.front());
}
return 0;
}