【打CF,学算法——三星级】CodeForces 701B Cells Not Under Attack (分析)

来源:互联网 发布:python 异常处理 编辑:程序博客网 时间:2024/05/22 17:27

【CF简介】


题目链接:CF 701B


题面:

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 andm 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 andm (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 integersxi andyi (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 firsti rooks are put.

Examples
Input
3 31 13 12 2
Output
4 2 0 
Input
5 21 55 1
Output
16 9 
Input
100000 1300 400
Output
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.

题意:

    一个n*n的棋盘,每次放入一颗棋子(每次棋子位置不同),则该棋子所在行和列都会受影响,共m次询问,问每次放入新的棋子后,未被影响的方格数量。


解题:

     初拿到这道题没什么想法,因为m为10^5,且时限为2s,估算应该是O(1)/O(nlogn)的解法比较合适。仔细分析,我们需要知道的是,插入新的棋子,有几个空位置被影响。为此,我们需呀知道原来棋盘的状态,看似好像很复杂,但实际上,我们只需要知道新插入位置所在行和所在列对棋盘的影响即可。分类讨论:如果,新行原来就是被影响的,那么这一行都不会有变化,同理,列也是如此,所以我们需要2个数组分别标记行和列的受影响情况,以及两个计数值记录受影响行数和列数。原来未受影响的列,产生的新影响数为(n-已受影响行数),行也是同理,注意下交叉点的判断即可。


代码:

#include <iostream>#include <cstdio>#include <cstring>#include <map>#define LL long longusing namespace std;bool row[100005],col[100005];int main(){    int m,rowc=0,colc=0,x,y;LL n,ans;scanf("%lld%d",&n,&m);ans=n*n;for(int i=0;i<m;i++){scanf("%d%d",&x,&y);if(row[x]&&col[y]);        else if(!row[x]&&!col[y]){ans--;ans=ans-(n-colc)+1;colc++;ans=ans-(n-rowc)+1;rowc++;}else if(row[x]){ans=ans-(n-rowc);colc++;}else{ans=ans-(n-colc);rowc++;}row[x]=col[y]=1;printf("%lld\n",ans);}return 0;}


0 0
原创粉丝点击