Your friend Ivan asked you to help him rearrange his desktop. The desktop can be represented as a rectangle matrix of size n × m n×m n×m consisting of characters ‘.’ (empty cell of the desktop) and ‘’ (an icon).
The desktop is called good if all its icons are occupying some prefix of full columns and, possibly, the prefix of the next column (and there are no icons outside this figure). In other words, some amount of first columns will be filled with icons and, possibly, some amount of first cells of the next (after the last full column) column will be also filled with icons (and all the icons on the desktop belong to this figure). This is pretty much the same as the real life icons arrangement.
In one move, you can take one icon and move it to any empty cell in the desktop.
Ivan loves to add some icons to his desktop and remove them from it, so he is asking you to answer q q q queries: what is the minimum number of moves required to make the desktop good after adding/removing one icon?
Note that queries are permanent and change the state of the desktop.
Input
The first line of the input contains three integers n n n, m m m and q ( 1 ≤ n , m ≤ 1000 ; 1 ≤ q ≤ 2 ⋅ 1 0 5 ) q (1≤n,m≤1000;1≤q≤2⋅10^5) q(1≤n,m≤1000;1≤q≤2⋅105) — the number of rows in the desktop, the number of columns in the desktop and the number of queries, respectively.
The next n n n lines contain the description of the desktop. The i i i-th of them contains m m m characters ‘.’ and '’ — the description of the i i i-th row of the desktop.
The next q q q lines describe queries. The i i i-th of them contains two integers x i x_i xi and y i ( 1 ≤ x i ≤ n ; 1 ≤ y i ≤ m ) y_i (1≤x_i≤n;1≤y_i≤m) yi(1≤xi≤n;1≤yi≤m) — the position of the cell which changes its state (if this cell contained the icon before, then this icon is removed, otherwise an icon appears in this cell).
Output
Print q q q integers. The i i i-th of them should be the minimum number of moves required to make the desktop good after applying the first i i i queries.
Examples
input4 4 8 ..** .*.. *... ...* 1 3 2 3 3 1 2 3 3 4 4 3 2 3 2 2
output
3 4 4 3 4 5 5 5
input
2 5 5 *...* ***** 1 3 2 2 1 3 1 5 2 3
output
2 3 3 3 2
题目大意
找到在每次添加或删除图标(如果该位置原来有图标就删除,否则添加)之后,将所有图标排列好所需的最小移动次数。
(注意: 1、每次的添加或删除图标操作属于永久性操作,对后序的添加或删除有影响。2、图标排列好是指一列一列地排图标,就像我们电脑桌面的自动排列图标。3、将图标从一个地方移动到最终的地方算一次移动)
解题思路
我们可以将桌面布局一列一列地存储进一个一维数组,因为我们不难发现图标排列好后它的图标是连续的。同时我们可以看看桌面中有多少个图标,这就是排列好后最后一个图标的位置。然后我们在添加或删除前先得知道现在需要移动的最小次数,其实就是从第一个位置到最后一个图标的位置所存在的空白格数(无图标)。现在我们就可以开始进行添加或删除了:
- 若给的位置在上一次最后一个图标位置内,则需要特别判断:原来该位置是图标,则将会变成无图标,移动次数 + 1 +1 +1,否则移动次数 − 1 -1 −1。
- 将该位置进行添加或删除,若该操作后需要判断:
- 若该位置修改成有图标,则图标数 + 1 +1 +1,也就是最后一个图标位置后移,因为这是一个新图标。同时,如果最后一个图标位置对应的是无图标,那么移动次数 + 1 +1 +1,需要补这个空位。
- 若该位置修改成无图标,则图标是 − 1 -1 −1,也就是最后一个图标位置前移,因为少了一个旧图标。
同时,如果前移前最后一个图标位置对应的是无图标,那么移动次数 − 1 -1 −1,无需补这个空。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3+10;
char mp[N*N];
int main()
{
int n, m, q;
scanf("%d %d %d", &n, &m, &q);
int pos = 0, ans = 0;
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++) //进行一列一列存储
{
scanf(" %c", &mp[j*n+i]);
if(mp[j*n+i] == '*') pos++; //记录图标数
}
}
for(int i=0; i<pos; i++)
if(mp[i] == '.') ans++; //记录移动次数
while(q--)
{
int x, y;
scanf("%d %d", &x, &y);
int p = (y-1)*n + (x-1); //将二维坐标转化为在一维中对应位置
if(p < pos) //若该位置在排列好后的图标位置范围内
{
if(mp[p] == '.') ans--; //变成图标,该位置不需要移动
else ans++; //位置变空,需要移动一个图标到这
}
mp[p] = (mp[p]=='.'? '*': '.'); //进行 添加或删除图标 操作
if(mp[p] == '*') //修改后该位置为图标 //添加
{
if(mp[pos] == '.') ans++; //添加后,最后一个图标位置若为空,则需要多移动一次
pos++; //图标数 +1
}
else //删除
{
pos--; //图标数 -1
if(mp[pos] == '.') ans--; //删除前最后一个图标位置为空,当图标数减少了,则该位置不需要移动
}
printf("%d\n", ans);
}
return 0;
}