【SPOJ DQUERY】区间数字统计
【链接】 我是链接,点我呀:)
【题意】
【题解】
因为区间的端点移动一个单位的话,只会涉及到一个元素的增多或减少。 因此可以用莫队算法来解决。 只需要开一个数组(大小1百万),用下标来快速检索元素的个数即可。【代码】
#include <bits/stdc++.h>
#define ll long long
using namespace std;
struct abc{
int l,r,id;
};
const int N = 30000;
const int Q = 200000;
int cnt[1000000+10];
abc query[Q+10];
int n,q,a[N+10];
int ans[Q+10],cur = 0;
bool cmp(abc a,abc b){
if (a.l/200==b.l/200){
return a.r<b.r;
}else{
return a.l<b.l;
}
}
int main(){
//freopen("D:\\rush.txt","r",stdin);
ios::sync_with_stdio(0),cin.tie(0);
cin >> n;
for (int i = 1;i <= n;i++) cin >> a[i];
cin >> q;
for (int i = 1;i <= q;i++){
int l,r;
cin >> l >> r;
query[i].l = l;query[i].r = r;query[i].id = i;
}
sort(query+1,query+1+q,cmp);
int nowl = query[1].l,nowr = query[1].r;
for (int i = nowl;i<=nowr;i++){
cnt[a[i]]++;
if (cnt[a[i]]==1){
cur++;
}
}
for (int i = 1;i <= Q;i++){
while (nowl<query[i].l){
cnt[a[nowl]]--;
if (cnt[a[nowl]]==0) cur--;
nowl++;
}
while (nowl>query[i].l){
nowl--;
cnt[a[nowl]]++;
if (cnt[a[nowl]]==1) cur++;
}
while (nowr<query[i].r){
nowr++;
cnt[a[nowr]]++;
if (cnt[a[nowr]]==1) cur++;
}
while(nowr>query[i].r){
cnt[a[nowr]]--;
if (cnt[a[nowr]]==0) cur--;
nowr--;
}
ans[query[i].id] = cur;
}
for (int i = 1;i <= q;i++){
cout<<ans[i]<<endl;
}
return 0;
}