1 条题解
-
0
题意:有一个长度为 n 的序列 A,给出 q 组询问,每次询问 A 在区间 [l,r] 内有几个 x。总共 T 组数据。
题意还是比较简明易懂的。n≤的数据范围,首先排除 O() 的暴力。
不妨把“在区间[l,r]内有几个 x”转化为“x 在区间 [l,r] 出现了几次”,那么可以考虑对于每一种 x 的值都开一个数组记录每个 x 出现的位置。每次询问时,分别二分出区间里最靠左的 x 编号和最靠右的 x 编号,两数相减再加一就是答案了。
但是 Ai≤,n≤,开一个 ×大小的数组显然是不科学的,那就把 Ai离散化一下,这样 Ai≤ 了,可是开一个 ×的数组依然吃不消。那么就开 个
vector
~#include<bits/stdc++.h> #define N 100005 using namespace std; int T; int n,m,q,a[N],b[N]; vector<int> c[N]; //a:原数组 b:离散化的a数组 c:存每个b[i]出现的位置 int main() { scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i = 1;i <= n;i++)scanf("%d",&a[i]),b[i] = a[i],c[i].clear(); //多测数据要清零。 sort(b+1,b+1+n); m = unique(b+1,b+1+n)-b-1; for(int i = 1;i <= n;i++)a[i] = lower_bound(b+1,b+m+1,a[i])-b,c[a[i]].push_back(i); scanf("%d",&q); while(q--) { int l,r,x,y; scanf("%d%d%d",&l,&r,&x); y = lower_bound(b+1,b+1+m,x)-b; if(b[y] != x)printf("0\n"); else printf("%d\n",upper_bound(c[y].begin(),c[y].end(),r)-lower_bound(c[y].begin(),c[y].end(),l)); //这里输出答案其实有一个抵消,就是用“第一个大于r”的位置去减掉“第一个大于等于l”的位置 } } return 0; }
- 1
信息
- ID
- 645
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 7
- 标签
- 递交数
- 18
- 已通过
- 9
- 上传者