传送门
有一个边长为 N N N 正方形的网格, ( i , j ) (i,j) (i,j) 为第 i i i 行第 j j j 列的正方形。
网格中央 ( N − 2 ) × ( N − 2 ) (N − 2)\times(N − 2) (N−2)×(N−2) 的每个方格上都有一个黑色的石头。底部和右侧的方格中,每个方格上都有一块白色的石头。
给出了 Q Q Q 个查询,有两种查询。它们的输入格式和描述如下:
在处理完所有 Q Q Q 次查询后,网格上有多少黑色石头?
提供一种不用数据结构的思路。
先把格局打开,把它想成一道思维题。
假设某一黑色区域宽为 x x x,长为 y y y,我们考虑一种修改,比如 1 k 1\ \ k 1 k。
不难发现修改后对 [ k + 1 , y ] [k+1,y] [k+1,y] 的 1 1 1 操作,都是固定的减去 x x x。
而 2 2 2 操作同理。
每操作一次都将黑色区域的长宽进行缩小,并用数组记录减少的黑色方块数即可。
#include
#define rep(i, a, b) for (int (i) = (a); (i) <= (b); ++(i))
#define fep(i, a, b) for (int (i) = (a); (i) < (b); ++(i))
#define int long long
#define N 200007
using namespace std;
int ans;
int n, q;
int x, y;
int opt, k;
int r[N],c[N];
signed main() {
scanf("%lld%lld", &n, &q);
x = y = n;
ans = (n - 2) * (n - 2);
while (q--) {
scanf("%lld%lld", &opt, &k);
if (opt == 1) {
if (k < y) {
ans -= x - 2;
while (y > k)
c[y--] = x - 2;
}
else
ans -= c[k];
}
else {
if (k < x) {
ans -= y - 2;
while (x > k)
r[x--] = y - 2;
}
else
ans -= r[k];
}
}
printf("%lld\n", ans);
return 0;
}