Blog of RuSun

\begin {array}{c} \mathfrak {One Problem Is Difficult} \\\\ \mathfrak {Because You Don't Know} \\\\ \mathfrak {Why It Is Diffucult} \end {array}

P5906 【模板】回滚莫队&不删除莫队

P5906 【模板】回滚莫队&不删除莫队

需要备份数组。注意块长 $len = \frac n {\sqrt m}$ ,特判 $n < \sqrt m$ 。

查看代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
void chkmax(int &x, int k)
{
(x < k) && (x = k);
}
void chkmin(int &x, int k)
{
(x > k) && (x = k);
}
template <class Type>
void read(Type &x)
{
char c;
bool flag = false;
while ((c = getchar()) < '0' || c > '9')
(c == '-') && (flag = true);
x = c - '0';
while ((c = getchar()) >= '0' && c <= '9')
x = (x << 3) + (x << 1) + c - '0';
(flag) && (x = ~x + 1);
}
const int N = 2e5 + 10;
int mx[N], mn[N], tmx[N], tmn[N];
int n, m, len, w[N], ans[N];
struct Query
{
int l, r, id;
friend bool operator<(const Query &x, const Query &y)
{
if (x.l / len != y.l / len)
return x.l < y.l;
return x.r < y.r;
}
} q[N];
vector<int> ws;
void add(int x, int &res)
{
chkmax(mx[w[x]], x);
chkmin(mn[w[x]], x);
chkmax(res, mx[w[x]] - mn[w[x]]);
}
int main()
{
read(n);
for (int i = 1; i <= n; i++)
{
read(w[i]);
ws.push_back(w[i]);
}
sort(ws.begin(), ws.end());
ws.erase(unique(ws.begin(), ws.end()), ws.end());
for (int i = 1; i <= n; i++)
w[i] = lower_bound(ws.begin(), ws.end(), w[i]) - ws.begin();
read(m);
for (int i = 0; i < m; i++)
{
read(q[i].l), read(q[i].r);
q[i].id = i;
}
len = n / sqrt(m);
chkmax(len, 1);
sort(q, q + m);
for (int x = 0; x < m;)
{
for (int i = 0; i < n; i++)
{
mx[i] = -1;
mn[i] = n;
}
int y = x;
for (; y < m && q[y].l / len == q[x].l / len; y++)
;
int p = q[x].l / len * len + len;
for (; x < y && q[x].r < p; x++)
{
int res = 0;
for (int k = q[x].l; k <= q[x].r; k++)
add(k, res);
ans[q[x].id] = res;
for (int k = q[x].l; k <= q[x].r; k++)
{
mx[w[k]] = -1;
mn[w[k]] = n;
}
}
for (int l, r = p - 1, res = 0; x < y; x++)
{
l = p;
while (r < q[x].r)
add(++r, res);
int tmp = res;
for (int k = q[x].l; k < p; k++)
{
tmx[w[k]] = mx[w[k]];
tmn[w[k]] = mn[w[k]];
}
while (l > q[x].l)
add(--l, res);
ans[q[x].id] = res;
res = tmp;
for (int k = q[x].l; k < p; k++)
{
mx[w[k]] = tmx[w[k]];
mn[w[k]] = tmn[w[k]];
}
}
}
for (int i = 0; i < m; i++)
printf("%d\n", ans[i]);
return 0;
}