离线,树状数组。
数据范围好像有点小,直接暴力可以过的。
我直接上了$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; }