题目大意
给出一个长度为 (n) 的序列 (a), 给出 (m) 个查询 (l) ,对于每个查询输出 ([l,n]) 的区间内不同数的个数。
分析:
将查询按照 (l) 的大小排序,从大到小的遍历,每次将 (>=) 当前 (l) 的位置的 (a[i]) 全部加入树状数组,让树状数组记录每个数是否出现过,每次的答案就是查询树状数组的总和。
代码:
#include <cstdio>
#include <algorithm>
const int MAX = 100010;
#define lowbit(x) x & -x
using namespace std;
typedef pair<int, int> pa;
int n, m, ans[MAX], a[MAX], c[MAX];
pa l[MAX];
const int lim = 1e5 + 1;
//template
template<class type>type _max(type _, type __) { return _ > __ ? _ : __; }
template<class type>type _min(type _, type __) { return _ < __ ? _ : __; }
template<class type>type _abs(type __) { return __ < 0 ? -__ : __; }
template<class type>type _gcd(type __, type ___) { return (!___) ? __ : gcd(___, __ % ___); }
template<class type>type _mod(type __, type ____) { if (__ >= 0 && __ < ____)return __; __ %= ____; if (__ < 0)__ += ____; return __; }
template<class type>type _qpow(type __, type ___, type ____) { type ans = 1; for (; ___; ___ >>= 1, __ = _mod(__ * __, ____))if (___ & 1)ans = _mod(ans * __, ____); return ans; }
//char buf[1 << 21], *p1 = buf, *p2 = buf;
//inline int getc() {
// return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
//}
inline int r() {
register int x = 0; register char ch = getchar();
for (; ch < '0' || ch > '9'; ch = getchar());
for (; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48);
return x;
}
inline double r_db() {
double s = 0.0; int f = 1; char c = getchar();
while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
while (c >= '0' && c <= '9') { s = s * 10 + (c ^ 48); c = getchar(); }
if (c == '.') { int k = 10; c = getchar(); while (c >= '0' && c <= '9') { s += (double)(c ^ 48) / k; k *= 10; c = getchar(); } }
return s;
}
//以上的template可以忽略
void add(int x) {
while (x <= lim) {
c[x]++;
x += lowbit(x);
}
}
int sum(int x) {
int ret = 0;
while (x) {
ret += c[x];
x -= lowbit(x);
}
return ret;
}
int main() {
while (~scanf("%d%d", &n, &m)) {
for (int i = 0; i < n; i++)
a[i] = r();
for (int i = 0; i < m; i++) {
l[i].first = r();
l[i].first--;
l[i].second = i;
}
sort(l, l + m);
int j = n - 1;
for (int i = m - 1; i >= 0; i--) {
while (j >= l[i].first) {
if (sum(a[j]) - sum(a[j] - 1) == 0)
add(a[j]);
j--;
}
ans[l[i].second] = sum(1e5);
}
for (int i = 0; i < m; i++)
printf("%d
", ans[i]);
}
}