传送门:https://codeforces.com/problemset/problem/220/B
题意:
给你n个数,m次询问,每次询问问你在区间l,r内有多少个数满足其值为其出现的次数
题解:
莫队算法
思路:每次区间向外扩的更新的过程中,检查该位置的数ai的出现次数是否已经达到ai或ai+1,以判断是否要更新结果。同理,区间收缩的时候判断ai出现次数是否达到ai或ai-1。
因为数据范围为1e9,所以需要离散化,方便记录每种数出现的次数
代码:
/**
* ┏┓ ┏┓
* ┏┛┗━━━━━━━┛┗━━━┓
* ┃ ┃
* ┃ ━ ┃
* ┃ > < ┃
* ┃ ┃
* ┃... ⌒ ... ┃
* ┃ ┃
* ┗━┓ ┏━┛
* ┃ ┃ Code is far away from bug with the animal protecting
* ┃ ┃ 神兽保佑,代码无bug
* ┃ ┃
* ┃ ┃
* ┃ ┃
* ┃ ┃
* ┃ ┗━━━┓
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛
*/
// warm heart, wagging tail,and a smile just for you!
//
// _ooOoo_
// o8888888o
// 88" . "88
// (| -_- |)
// O = /O
// ____/`---'\____
// .' | |// `.
// / ||| : |||//
// / _||||| -:- |||||-
// | | \ - /// | |
// | \_| ''---/'' | |
// .-\__ `-` ___/-. /
// ___`. .' /--.-- `. . __
// ."" '< `.___\_<|>_/___.' >'"".
// | | : `- \`.;` _ /`;.`/ - ` : | |
// `-. \_ __ /__ _/ .-` / /
// ======`-.____`-.___\_____/___.-`____.-'======
// `=---='
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// 佛祖保佑 永无BUG
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********
")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]
"
#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]
"
#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]
"
const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 3e5 + 5;
const int INF = 0x3f3f3f3f;
const LL INFLL = 0x3f3f3f3f3f3f3f3f;
int a[maxn];
int pos[maxn];
struct node {
int l, r, id;
} q[maxn];
bool cmp(node a, node b) {
if(pos[a.l] == pos[b.l]) return a.r < b.r;
return pos[a.l] < pos[b.l];
}
int b[maxn];
int cnt;
int Ans = 0;
int id[maxn];
int ans[maxn];
int vis[maxn];
int get_id(int x) {
return lower_bound(b + 1, b + 1 + cnt, x) - b;
}
void add(int x) {
if(vis[id[x]] == a[x]) {
Ans--;
}
vis[id[x]]++;
if(vis[id[x]] == a[x]) {
Ans++;
}
}
void del(int x) {
if(vis[id[x]] == a[x]) {
Ans--;
}
vis[id[x]]--;
if(vis[id[x]] == a[x]) {
Ans++;
}
}
int main() {
#ifndef ONLINE_JUDGE
FIN
#endif
int n, m;
scanf("%d%d", &n, &m);
int sz = sqrt(n);
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
b[i] = a[i];
pos[i] = i / sz;
}
for(int i = 1; i <= m; i++) {
scanf("%d%d", &q[i].l, &q[i].r);
q[i].id = i;
}
sort(q + 1, q + 1 + m, cmp);
sort(b + 1, b + n + 1);
cnt = unique(b + 1, b + n + 1) - b - 1;
for(int i = 1; i <= n; i++) {
id[i] = get_id(a[i]);
}
int L = 1, R = 0;
a[0] = -1;
for(int i = 1; i <= m; i++) {
while(R < q[i].r) {
R++;
add(R);
}
while(L < q[i].l) {
del(L);
L++;
}
while(R > q[i].r) {
del(R);
R--;
}
while(L > q[i].l) {
L--;
add(L);
}
ans[q[i].id] = Ans;
}
for(int i = 1; i <= m; i++) {
printf("%d
", ans[i]);
}
return 0;
}
/*
1
0
2
1
1
3*/