数组 a[1..n](1≤a[i]≤n),m 次询问 [l,r]:区间内元素是否恰为 1..len 的一个排列(len=r-l+1)。
len*(len+1)/2条件 2 等价于:区间内每个元素的「上一次出现位置」均 < l。
sum[i]:前缀和pre[i]:a[i] 上一次出现的索引(首次为 -1)const int N = 1e6+100;
int dat[2*N], nn;
void init(int n) {
nn = 1; while (nn < n) nn <<= 1;
fill(dat, dat+2*nn, -INF);
}
void update(int k, int v) {
k += nn-1; dat[k] = v;
while (k) { k = (k-1)/2; dat[k] = max(dat[k*2+1], dat[k*2+2]); }
}
int query(int L, int R, int k, int l, int r) {
if (R<=l || r<=L) return -INF;
if (L<=l && r<=R) return dat[k];
return max(query(L,R,k*2+1,l,(l+r)/2), query(L,R,k*2+2,(l+r)/2,r));
}
while (m--) {
int l, r; scanf("%d%d", &l, &r);
int len = r-l+1;
ll need = 1LL*len*(len+1)/2;
if (sum[r]-sum[l-1] != need) { puts("NO"); continue; }
if (query(l-1, r, 0, 0, nn) < l) puts("YES");
else puts("NO");
}
max(pre[l..r]) < l ⇔ 无重复