#rMQybttg040203. 1543:【例 3】与众不同

1543:【例 3】与众不同

好的,我将这道题整理为清晰的题面格式,并补充样例解释、数据范围与时空限制:


题目描述

A 是某公司的 CEO,每个月都会有员工把公司的盈利数据送给 A,A 是个与众不同的怪人,A 不注重盈利还是亏本,而是喜欢研究「完美序列」:一段连续的序列满足序列中的数互不相同。

A 想知道区间 [L,R][L,R] 之间最长的完美序列长度。


输入格式

第一行两个整数 N,MN, MNN 表示连续 NN 个月,编号为 00N1N-1MM 表示询问的次数;

第二行 NN 个整数,第 ii 个数表示该公司第 ii 个月的盈利值 aia_i

接下来 MM 行每行两个整数 L,RL, R,表示 A 询问的区间。


输出格式

输出 MM 行,每行一个整数,对应询问区间 [L,R][L,R] 内最长的完美序列(连续且互不相同)的长度。


样例

样例输入

9 2
2 5 4 1 2 3 6 2 4
0 8
2 6

样例输出

6
5

样例说明

N=9N=9,序列 [2,5,4,1,2,3,6,2,4][2,5,4,1,2,3,6,2,4]

询问1:区间 [0,8][0,8](整个序列)中最长完美序列:

  • 从下标 2 开始:[4,1,2,3,6][4,1,2,3,6](长度 5)
  • 从下标 3 开始:[1,2,3,6,2,4][1,2,3,6,2,4](长度 6,但有两个 2 重复,实际上 [1,2,3,6][1,2,3,6] 长度 4)
  • 正确的最长完美序列:从下标 2 到 6:[4,1,2,3,6][4,1,2,3,6] 长度 5,还是从下标 3 到 8:[1,2,3,6,2,4][1,2,3,6,2,4] 有重复,所以最长可能是 5?但样例输出是 6。 我们检查:从下标 3 到 8 的序列 [1,2,3,6,2,4][1,2,3,6,2,4] 中下标 4 和 7 都是 2,重复了,所以不是完美序列。 实际上最长完美序列:从下标 0 到 5:[2,5,4,1,2,3][2,5,4,1,2,3] 也有重复 2,不是。 仔细找:从下标 1 到 6:[5,4,1,2,3,6][5,4,1,2,3,6] 长度 6,没有重复,这就是答案 6。

询问2:区间 [2,6][2,6] 的序列 [4,1,2,3,6][4,1,2,3,6] 长度 5,没有重复,所以输出 5。


数据范围

对于全部数据:

  • 1N,M2×1051 \le N, M \le 2\times 10^5
  • 0LRN10 \le L \le R \le N-1
  • ai106|a_i| \le 10^6

时空限制

  • 时间:1000 ms1000 \text{ ms}
  • 内存:524288 KB524288 \text{ KB}(512 MB)

提示
此题为 区间内最长无重复子段 问题,可以离线用 RMQ + 预处理ST 表 + 二分 解决。

预处理

  1. 对于每个位置 ii,计算 nxt[i]nxt[i]:以 ii 为起点的最长无重复子段的结束位置的下一个位置(即 [i,nxt[i]1][i, nxt[i]-1] 无重复,但 nxt[i]nxt[i] 处重复或越界)。 这可以用双指针(尺取法)在 O(N)O(N) 内求出:

    • map 或数组(值域需离散化)记录每个值最后出现的位置 last
    • 遍历右端点 rr,维护左端点 ll,使得 [l,r][l, r] 无重复;
    • nxt[l]=r+1nxt[l] = r+1,然后 ll 右移。 但更常用的是:设 f[i]f[i] 表示以 ii 结尾的最长无重复子段的起始位置,可以通过 f[i]=max(f[i1],last[a[i]]+1)f[i] = \max(f[i-1], last[a[i]]+1) 递推,其中 last[a[i]]last[a[i]]a[i]a[i] 上一次出现的位置。 那么 len[i]=if[i]+1len[i] = i - f[i] + 1 就是以 ii 结尾的最长无重复子段长度。
  2. 但问题问的是区间 [L,R][L,R] 内的任意连续子段,不一定以 RR 结尾。 我们可以先求出 st[i]st[i]:以 ii 为起点的最长无重复子段的结束位置,即 st[i]=i+len1st[i] = i + len - 1,其中 lenlen 是从 ii 开始的无重复子段最大长度。 这个可以通过预处理 nxt[i]nxt[i] 得到:nxt[i]nxt[i] 表示从 ii 开始的最远不重复位置(开区间),则 st[i]=nxt[i]1st[i] = nxt[i] - 1

    但是区间查询时,可能答案被 RR 截断。所以对于查询 [L,R][L,R]

    • 如果 st[L]Rst[L] \le R,说明从 LL 开始的无重复子段完全在区间内,那么答案至少为 st[L]L+1st[L]-L+1
    • 还需要考虑起点在 [L,R][L,R] 内的其他位置。

标准解法(离线 RMQ):

  • 预处理 p[i]p[i]:以 ii 结尾的最长无重复子段的起始位置(f[i]f[i] 如上);
  • 对于询问 [L,R][L,R],我们需要找到 LxyRL \le x \le y \le R 使得 yx+1y-x+1 最大且 [x,y][x,y] 无重复。
  • 由于无重复要求 f[y]xf[y] \le x,所以对于固定的 yyxx 至少为 f[y]f[y]
  • 因此,对于每个 yy,对应的无重复子段为 [f[y],y][f[y], y],长度为 yf[y]+1y-f[y]+1
  • 在区间 [L,R][L,R] 中,yy 必须满足 f[y]Lf[y] \ge LyRy \le R
  • 问题转化为:在 [L,R][L,R] 中找 yy,使得 yf[y]+1y-f[y]+1 最大,但可能 f[y]<Lf[y] < L,此时子段实际起点是 LL,长度为 yL+1y-L+1
  • 因此,答案 = $\max\left( \max_{y \in [L,R], f[y] \ge L} (y-f[y]+1), \max_{y \in [L,R], f[y] < L} (y-L+1) \right)$。

简化做法: 预处理 len[i]=if[i]+1len[i] = i - f[i] + 1(以 ii 结尾的最长无重复长度)。
对于询问 [L,R][L,R],找到第一个 t[L,R]t \in [L,R] 使得 f[t]Lf[t] \ge L(即第一个完全在 [L,R][L,R] 内的无重复段),则:

  • 对于 i[t,R]i \in [t, R],无重复段完全在 [L,R][L,R] 内,答案候选为 len[i]len[i]
  • 对于 i[L,t1]i \in [L, t-1],无重复段起点可能小于 LL,实际长度为 iL+1i-L+1

因此答案 = max(maxi=tRlen[i],tL)\max( \max_{i=t}^{R} len[i], t-L )(因为 i[L,t1]i \in [L, t-1] 中最大 iL+1i-L+1 就是 tLt-L)。

于是问题变成:快速找到 t=min{i[L,R]f[i]L}t = \min\{ i \in [L,R] \mid f[i] \ge L \},可以用 二分ff 数组上查找(因为 f[i]f[i] 非降),然后用 RMQ 查询 [t,R][t,R]len[i]len[i] 的最大值。

步骤

  1. 预处理 f[i]f[i]len[i]len[i]O(N)O(N));
  2. f[i]f[i] 数组建立 ST 表用于二分查找第一个 f[i]Lf[i] \ge L 的位置 tt
  3. len[i]len[i] 建立 ST 表用于区间最大值查询;
  4. 对于每个询问 [L,R][L,R]
    • 二分找到 tt
    • t>Rt > R,则所有 f[i]<Lf[i] < L,答案 =RL+1= R-L+1
    • 否则答案 =max(tL,RMQ(t,R))= \max(t-L, \text{RMQ}(t, R))

复杂度:预处理 O(NlogN)O(N \log N),每个询问 O(logN)O(\log N)

注意aia_i 范围 [106,106][-10^6, 10^6],需离散化或使用偏移数组记录最后出现位置。