CF220B Little Elephant and Array
像这样对于出现次数有限定的计数,并且可以离线的问题,我们可以考虑莫队来做。
那么其实这道题想到莫队就很显然了,相当于每次我们直接看一下当前桶是不是等于其本身即可。
代码:
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native")
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
template <typename T>
inline void read(T &x){
x=0;char ch=getchar();bool f=false;
while(!isdigit(ch)){if(ch=='-'){f=true;}ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
x=f?-x:x;
return ;
}
template <typename T>
inline void write(T x){
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10^48);
return ;
}
const int N=1e5+5;
#define ll long long
int n,m,k;
int bl[N],vis[N];
ll a[N],Ans[N],pre[N];
struct Query{int l,r,id;}Q[N];
gp_hash_table<long long,int>cnt;
ll Now;
inline void Add(int x){
cnt[a[x]]++;
if(cnt[a[x]]==a[x]) Now++;
else if(cnt[a[x]]==a[x]+1) Now--;
return ;
}
inline void Del(int x){
cnt[a[x]]--;
if(cnt[a[x]]==a[x]) Now++;
else if(cnt[a[x]]==a[x]-1) Now--;
return ;
}
inline bool Cmp(Query x,Query y){return bl[x.l]^bl[y.l]?bl[x.l]<bl[y.l]:bl[x.l]&1?x.r<y.r:x.r>y.r;}
int main(){
read(n);read(m);
for(int i=1;i<=n;i++) read(a[i]);
const int t=sqrt(m);
for(int i=1;i<=m;i++) read(Q[i].l),read(Q[i].r),Q[i].id=i;
for(int i=1;i<=n;i++) bl[i]=(i-1)/t+1;
sort(Q+1,Q+m+1,Cmp);
int l=1,r=0;
for(int i=1;i<=m;i++){
while(l>Q[i].l) Add(--l);
while(r<Q[i].r) Add(++r);
while(l<Q[i].l) Del(l++);
while(r>Q[i].r) Del(r--);
Ans[Q[i].id]=Now;
}
for(int i=1;i<=m;i++) write(Ans[i]),putchar('
');
return 0;
}