离线,树状数组。
数据范围好像有点小,直接暴力可以过的。
我直接上了$n,Q≤100000$的做法:只需要判断区间上比$x$小的数字有几个即可,可以对询问进行离线操作,从左到右一个一个数字插入到树状数组中。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <cmath>
using namespace std;
int n,m;
struct X
{
int id;
int op;
int pos;
int val;
int y;
}s[20010];
int sz;
int ans[10010][2];
int c[10100],a[10100];
int lowbit(int x)
{
return x&(-x);
}
void update(int x)
{
while(x<=10000)
{
c[x]++;
x = x+lowbit(x);
}
}
int get(int x)
{
int res = 0;
while(x>0)
{
res = res + c[x];
x = x-lowbit(x);
}
return res;
}
bool cmp(X a,X b)
{
return a.pos<b.pos;
}
bool cmp2(X a,X b)
{
if(a.id == b.id) return a.op < b.op;
return a.id < b.id;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=m;i++)
{
int L,R,v; scanf("%d%d%d",&L,&R,&v);
s[sz].id = i;
s[sz].op = 0;
s[sz].pos = L-1;
s[sz].val = a[v];
s[sz].y = v;
sz++;
s[sz].id = i;
s[sz].op = 1;
s[sz].pos = R;
s[sz].val = a[v];
s[sz].y = v;
sz++;
}
sort(s,s+sz,cmp);
int p = 0;
for(int i=0;i<=n;i++)
{
if(i>0) update(a[i]);
while(1)
{
if(p<sz && s[p].pos==i)
{
ans[s[p].id][s[p].op] = get(s[p].val-1);
p++;
}
else break;
}
}
sort(s,s+sz,cmp2);
int id = 0;
for(int i=0;i<sz;i=i+2)
{
id++;
int num1 = ans[id][1] - ans[id][0];
int num2 = s[i].y - s[i].pos - 1;
if(num1 == num2) printf("Yes
");
else printf("No
");
}
return 0;
}