1.前言
这道题不用线段树是真的抽象。。。
2.题解
我们只分析在列上放棋子
0.变量
以右下角为(1,1)
M
i
n
1
Min1
Min1 :最大的修改行上的
x
x
x
M
i
n
2
Min2
Min2 :最大的修改列上的
x
x
x
M
i
n
l
[
i
]
Minl[i]
Minl[i] :第
i
i
i列的最大的修改行的x
M
i
n
r
[
i
]
Minr[i]
Minr[i] :第
i
i
i行的最大的修改列的x
1. 若 x ∈ [ 1 , M i n 1 ] x \in [1, Min1] x∈[1,Min1]
如图
则粉色那条线的
M
i
n
l
Minl
Minl值不会再被更新
所以
M
i
n
l
[
i
]
=
M
i
n
2
(
i
∈
[
x
,
M
i
n
1
]
)
Minl[i] = Min2 (i \in [x, Min1])
Minl[i]=Min2(i∈[x,Min1]) (更新)
v
a
l
+
=
M
i
n
l
[
x
]
val += Minl[x]
val+=Minl[x]
注:灰色那条线是
x
x
x
2. x ∈ ( M i n 1 , n − 2 ] x \in (Min1, n - 2] x∈(Min1,n−2]
如图
则灰色这条线不会修改任意的
M
i
n
l
Minl
Minl
v
a
l
+
=
M
i
n
l
[
x
]
val += Minl[x]
val+=Minl[x]
注:灰色那条线是
x
x
x
3.代码
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
template <typename T> void read (T &x) {x = 0; T f = 1;char tem = getchar ();while (tem < '0' || tem > '9') {if (tem == '-') f = -1;tem = getchar ();}while (tem >= '0' && tem <= '9') {x = (x << 1) + (x << 3) + tem - '0';tem = getchar ();}x *= f;}
template <typename T> void write (T x) {if (x < 0) {x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
template <typename T> T Max (T x, T y) { return x > y ? x : y; }
template <typename T> T Min (T x, T y) { return x < y ? x : y; }
template <typename T> T Abs (T x) { return x > 0 ? x : -x; }
const int Maxn = 2 * 1e5 + 5;
LL n, q, ans;
LL Min1, Min2;
LL Minl[Maxn], Minr[Maxn];
int main () {
read (n); read (q);
Min1 = Min2 = n;
for (int i = 1; i <= n; i++) Minl[i] = Minr[i] = n;
for (int i = 1; i <= q; i++) {
LL type, x;
read (type); read (x);
if (type == 1) {
if (x < Min1) {//放在[1, Min1]中
for (int i = x; i <= Min1; i++) {
Minl[i] = Min (Minl[i], Min2);
}
}
ans += Minl[x] - 2;
Min1 = Min (Min1, x);
}
else {
if (x < Min2) {
for (int i = x; i <= Min2; i++) {
Minr[i] = Min (Minr[i], Min1);
}
}
ans += Minr[x] - 2;
Min2 = Min (Min2, x);
}
}
write ((n - 2) * (n - 2) - ans);
return 0;
}