P9991 [Ynoi Easy Round 2023] TEST_107 题解
先考虑暴力
我们肯定是把区间中某一个数全部删掉。维护
考虑
此外每个区间中每个不同的数最后一个出现位置有
于是我们只需要处理三部分:
- 对于所有
,求 最大值。 - 对于
,求 最大值。 - 对于
,求 最大值。
三个答案取最大值即为答案。
先考虑第一个。可以离线枚举
后面两个类似,以第二个为例。我们对于每个区间要求最大的
于是就做完了,时间复杂度 basic_string
替代 vector
并且开快读和各种优化。感觉这个做法其实不很优美。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <string>
using namespace std;
const int N = 2e6 + 5;
int lstpos[N];
namespace FastIO {
char* p1, * p2, buf[1 << 14];
#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, (1 << 14), stdin), p1 == p2) ? EOF : *p1++)
template <typename T>
inline void read(T& x)
{
x = 0;
char ch = getchar();
while (ch < '0' || ch > '9') {
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
}
template <typename T>
void write(T x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9) write(x / 10);
putchar(x % 10 ^ 48);
}
template <typename T>
inline void writeln(T x, char sep = '\n') {
write(x);
putchar(sep);
}
}
using namespace FastIO;
int n, m;
int a[N], g[N];
int gpos[N];
int LG2[N];
class ST
{
public:
int f[22][N];
bool flag;
void Init(int* a)
{
if (flag) memset(f, 0x3f, sizeof f);
else memset(f, 0, sizeof f);
for (int i = 1; i <= n; i++) f[0][i] = a[i];
for (int j = 1; j <= 21; j++)
{
for (int i = 1; i + (1 << j) - 1 <= n; i++)
{
if (flag) f[j][i] = min(f[j - 1][i], f[j - 1][i + (1 << (j - 1))]);
else f[j][i] = max(f[j - 1][i], f[j - 1][i + (1 << (j - 1))]);
}
}
}
int query(const int& l, const int& r)
{
int p(LG2[r - l + 1]);
if (flag) return min(f[p][l], f[p][r - (1 << p) + 1]);
return max(f[p][l], f[p][r - (1 << p) + 1]);
}
}s1;
int ans[N];
int L[N], R[N];
basic_string<int> v[N];
int l, r, x;
class SegmentTree
{
public:
struct Node
{
int l, r, maxn;
}tr[N << 2];
void build(int u, int l, int r, int* a)
{
tr[u] = { l, r, a[l] };
if (l == r) return;
int mid = l + r >> 1;
build(u << 1, l, mid, a);
build(u << 1 | 1, mid + 1, r, a);
tr[u].maxn = max(tr[u << 1].maxn, tr[u << 1 | 1].maxn);
}
void update(int u)
{
if (tr[u].l == tr[u].r)
{
tr[u].maxn = 0;
return;
}
int mid = tr[u].l + tr[u].r >> 1;
if (x <= mid) update(u << 1);
else update(u << 1 | 1);
tr[u].maxn = max(tr[u << 1].maxn, tr[u << 1 | 1].maxn);
}
int query(int u)
{
if (tr[u].l >= l and tr[u].r <= r) return tr[u].maxn;
int res(0), mid(tr[u].l + tr[u].r >> 1);
if (l <= mid) res = query(u << 1);
if (r > mid) res = max(res, query(u << 1 | 1));
return res;
}
}sgt;
int b[N];
basic_string<int> place[N];
int main()
{
for (int i = 2; i < N; i++) LG2[i] = LG2[i / 2] + 1;
read(n), read(m);
for (int i = 1; i <= n; i++)
{
read(a[i]);
lstpos[i] = g[a[i]];
place[lstpos[i]] += i;
g[a[i]] = i;
b[i] = i - lstpos[i] - 1;
}
memset(g, 0, sizeof g);
for (int i = n; i >= 1; i--)
{
gpos[i] = (g[a[i]] ? g[a[i]] : n + 1);
g[a[i]] = i;
}
s1.flag = 1;
s1.Init(lstpos);
for (int i = 1; i <= m; i = -~i)
{
int l, r;
read(l), read(r);
L[i] = l, R[i] = r;
v[l] += i;
int nl = l, nr = r, pos = -1;
while (nl <= nr)
{
int mid(nl + nr >> 1);
if (s1.query(mid, r) < l)
{
pos = mid;
nl = mid + 1;
}
else
{
nr = mid - 1;
}
}
ans[i] = max(ans[i], pos - l);
}
s1.flag = 0;
s1.Init(gpos);
for (int i = 1; i <= m; i = -~i)
{
int l = L[i], r = R[i];
int nl = l, nr = r, pos = n + 1;
while (nl <= nr)
{
int mid((nl + nr) >> 1);
if (s1.query(l, mid) > r)
{
pos = mid;
nr = mid - 1;
}
else
{
nl = mid + 1;
}
}
ans[i] = max(ans[i], r - pos);
}
sgt.build(1, 1, n, b);
int lpos = 0;
for (int i = n; i >= 0; i--)
{
if (v[i].size())
{
lpos = i;
break;
}
}
for (int i = 0; i <= lpos; i++)
{
l = i;
for (auto& id : v[i])
{
int r = R[id];
::r = r;
ans[id] = max(ans[id], sgt.query(1));
}
for (auto& p : place[i])
{
::x = p;
sgt.update(1);
}
}
for (int i = 1; i <= m; i++)
{
writeln(ans[i]);
}
return 0;
}
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!