题解:P17234 [Algo Beat Contest 017 C] 交互题
FlowerAccepted · · 题解
0x00 前言
蒟蒻的痛。想了两小时有馀,我须省我是杂鱼!
0x01 解题思路
转化一下题面意思。
Therefore
然后考虑猫耳小(mex)的
设
Therefore 合法区间
那么两式均为
但是我们不能忘掉,猫耳小为
即然我们统计的是
那做不到
这里有单调性,没
那么预处理总猫耳小即可,后面枚举
零,在猫耳小问题中是一个特殊的存在。没有比零小的非负整数!
如果
特殊对待
另一种思路,核心思想和上面的一样:
用 continue,这样可以省去很多判断。
0x02 代码呈现
屎山版:
这里有些注释是赛时防止自己糊涂的。
#include "bits/stdc++.h"
using namespace std;
#define ch(opt, tar, ...) (tar = opt({tar, __VA_ARGS__}))
#define inlfc __attribute__((always_inline)) inline
#define isz(x) ((int)x.size())
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
const int MAXN = 2e5 + 5, INF = 2e9;
int a[MAXN], lmin[MAXN] = {INF}, rmin[MAXN], l[MAXN], r[MAXN];
vector<int> pos[MAXN];
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int n, wholemex;
ll ans = 0;
cin >> n;
for (int i = 1; i <= n; i ++)
cin >> a[i];
for (int i = 1; i <= n; i ++)
pos[a[i]].push_back(i);
if (!pos[0].size()) {
cout << 0; // 答案为棍母
return 0;
}
for (wholemex = 0; wholemex <= n; wholemex ++)
if (!pos[wholemex].size()) break; // 计算 a 的猫耳小
for (int i = 1; i <= n; i ++)
lmin[i] = min(lmin[i - 1], a[i]);
for (int x = 1, i = n; x <= wholemex && i; x ++) {
while (lmin[i - 1] < x) i --; // 单调不增算 L
l[x] = i; // l_x = i_min | a_i < x
}
rmin[n + 1] = INF;
for (int i = n; i; i --)
rmin[i] = min(rmin[i + 1], a[i]);
for (int x = 1, i = 1; x <= wholemex && i <= n; x ++) {
while (rmin[i + 1] < x) i ++; // 单调不减算 R
r[x] = i; // r_x = i_max | a_i < x
}
// x = 0
for (int i = 1, j = 0; i <= n; i ++) {
if (a[i]) j ++;
else j = 0;
ans += j; // 连续块长度为 j,以 i 为右端点可以贡献 j 个区间
}
// x > 0
// 性质:a[L, R_x] ≠ x
for (int x = 1; x <= wholemex; x ++) {
if (!pos[x].size()) continue; // actually only when x=wholemex QwQ
int L = l[x], R = r[x], _l, _r;
auto it = lower_bound(pos[x].begin(), pos[x].end(), L); // 迭代器
if (it != pos[x].end()) _r = *it;
else _r = n + 1; // 后面没有 x 了
if (it != pos[x].begin()) _l = *(it - 1);
else _l = 0; // 前面没有 x 了
if (_r <= R) continue; // [L,R]中有x
ans += (ll)(L - _l) * (_r - R); // 别写反
}
cout << ans;
return 0;
}
0x03 复杂度分析
线性套二分,
0x~0 后记
数学老师:
时间不早了,求管理员先过下谢谢/bq。