题意:给了一串长度为n的序列,每个数都不相同,随后是m个询问,L R K 问将[L,R]中的数从小到大排序后,原来第K个数是否还是第K个。
分析:用主席树维护这个序列,对于每个询问,查询这个区间里比a[K]大的数的个数Q,如果R - Q == k 输出 Yes。具体见代码。
以下是代码。
struct {
int lc, rc, sum;
}st[MAXN * 40];
int rt[MAXN], a[MAXN], n, m, x, y, k, cnt;
void update(int l, int r, int &x, int y, int pos) {
st[++cnt] = st[y], st[cnt].sum++, x = cnt;
if (l == r)return;
int mid = (l + r) / 2;
if (pos <= mid)update(l, mid, st[x].lc, st[y].lc, pos);
else update(mid + 1, r, st[x].rc, st[y].rc, pos);
}
int query(int l, int r, int x, int L,int R) {
if (L > R)return 0;
if (L <= l&&r <= R) {
return st[x].sum;
}
int mid = (l + r) >> 1;
if (R <= mid)return query(l, mid, st[x].lc, L, R);
else if (L > mid)return query(mid + 1, r, st[x].rc, L, R);
else
{
return query(l, mid, st[x].lc, L, R) + query(mid + 1, r, st[x].rc, L, R);
}
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i)scanf("%d", &a[i]);
for (int i = 1; i <= n; ++i)update(1, n, rt[i], rt[i - 1], a[i]);
while (m--) {
scanf("%d%d%d", &x, &y, &k);
int num = query(1, n, rt[y], a[k] + 1, n)
- query(1, n, rt[x - 1], a[k] + 1, n);
if (num == y - k)printf("Yes\n");
else printf("No\n");
}
}