题意:
有n个元素的序列,和m个询问, 每次询问[l,r]的区间是不是1~r-l+1的一个排列。
思路:
对于一个长度为len的区间, 如果最大值为len,最小值为1,并且区间元素没有重复的话就说明它是一个1~len的排列, 最值可以用线段树来求, 对于区间重复的话可以先预处理每个元素的下一个出现位置nxt[i], 如果区间里面所有元素的下一个出现位置都大于r的话, 就表示这个区间没有重复, 所以可以转化成求nxt数组的区间最小值, 也可以用线段树。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <stack>
#include <cmath>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <ctime>
#include <cstdlib>
using namespace std;
#define mxn 1000200
#define mxe 200020
#define mod 10000007
#define LL long long
#define inf 0x3f3f3f3f
#define vi vector<int>
#define PB push_back
#define MP make_pair
#define pii pair<int, int>
#define G(i, u) for(int i = fst[u]; ~i; i = nxt[i])
#define F(i, n) for(int i = 1; i <= n; ++i)
#pragma comment(linker,"/STACK:1024000000,1024000000")
#define ls (i << 1)
#define rs (ls | 1)
#define md ((ll + rr) >> 1)
int a[mxn], n, m;
int nxt[mxn], pre[mxn];
int mi[mxn << 2], mx[mxn << 2], s[mxn << 2];
void build(int ll, int rr, int i) {
if(ll == rr) {
mx[i] = mi[i] = a[ll];
s[i] = nxt[ll];
return;
}
build(ll, md, ls);
build(md + 1, rr, rs);
mx[i] = max(mx[ls], mx[rs]);
mi[i] = min(mi[ls], mi[rs]);
s[i] = min(s[ls], s[rs]);
}
int qm(int t, int l, int r, int ll, int rr, int i) {
if(ll == l && rr == r) {
if(t == 0)
return mi[i];
if(t == 1)
return mx[i];
return s[i];
}
if(r <= md) return qm(t, l, r, ll, md, ls);
if(l > md) return qm(t, l, r, md + 1, rr, rs);
if(t == 0)
return min(qm(t, l, md, ll, md, ls), qm(t, md + 1, r, md + 1, rr, rs));
if(t == 1)
return max(qm(t, l, md, ll, md, ls), qm(t, md + 1, r, md + 1, rr, rs));
if(t == 2)
return min(qm(t, l, md, ll, md, ls), qm(t, md + 1, r, md + 1, rr, rs));
}
int main() {
while(scanf("%d%d", &n, &m) != EOF) {
for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
memset(pre, -1, sizeof pre);
for(int i = n; i >= 1; --i) {
if(pre[a[i]] == -1) {
nxt[i] = n + 1;
pre[a[i]] = i;
}
else {
nxt[i] = pre[a[i]];
pre[a[i]] = i;
}
}
build(1, n, 1);
while(m--) {
int l, r;
scanf("%d%d", &l, &r);
int len = r - l + 1;
if(qm(0, l, r, 1, n, 1) == 1 && qm(1, l, r, 1, n, 1) == len && qm(2, l, r, 1, n, 1) > r)
puts("YES");
else
puts("NO");
}
}
return 0;
}