小象喜欢玩数组。他有一个数组a,由n个正整数组成,从1到n进行索引。让我们用索引i表示数字ai。
此外,小象对数组还有m个查询,每个查询的特征是一对整数lj和rj(1 ≤ lj ≤ rj ≤ n)。对于每一个查询LJ,小的大象必须计数,有多少个X数字存在,这样X数恰好在alj,alj+1…arj出现,X数为1。
帮助小象计算所有问题的答案。
输入
第一行包含两个空格分隔的整数n和m(1 ≤ n, m ≤ 105)-数组a的大小和对它的查询数。下一行包含n个空格分隔的正整数a1、a2、…、an(1 ≤ ai ≤ 109)。接下来的m行包含查询的描述,每行一个。这些行的j-th包含对j-th查询的描述,即两个空格分隔的整数lj和rj(1 ≤ lj ≤ rj ≤ n)。
输出
在m行中打印m个整数-查询的答案。第j行应该包含第j个查询的答案。
Examples
Input
7 2
3 1 2 2 3 3 7
1 7
3 4
Output
3
1
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int maxn = 1e5 + 10; int n, m, nowans, block, l, r; int a[maxn], bl[maxn], ans[maxn], cnt[maxn]; struct node { int l, r, id; bool operator<(const node &x) const { return bl[l] == bl[x.l] ? r < x.r : bl[l] < bl[x.l]; } } info[maxn]; inline void add(int x) { if (a[x] > n) return; if (cnt[a[x]] == a[x]) nowans--; cnt[a[x]]++; if (cnt[a[x]] == a[x]) nowans++; } inline void dec(int x) { if (a[x] > n) return; if (cnt[a[x]] == a[x]) nowans--; cnt[a[x]]--; if (cnt[a[x]] == a[x]) nowans++; } int main() { scanf("%d%d", &n, &m); block = (int) sqrt(n); for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); bl[i] = i / block; } for (int i = 1; i <= m; i++) { scanf("%d%d", &info[i].l, &info[i].r); info[i].id = i; } sort(info + 1, info + m + 1); memset(cnt, 0, sizeof(cnt)); l = 1; r = 0; for (int i = 1; i <= m; i++) { while (l < info[i].l) dec(l++); while (l > info[i].l) add(--l); while (r < info[i].r) add(++r); while (r > info[i].r) dec(r--); ans[info[i].id] = nowans; } for (int i = 1; i <= m; i++) printf("%d ", ans[i]); }