Given a sequence of n numbers a1, a2, …, an and a number of d-queries. A d-query is a pair (i, j) (1 ≤ i ≤ j ≤ n). For each d-query (i, j), you have to return the number of distinct elements in the subsequence ai, ai+1, …, aj.
Input
Line 1: n (1 ≤ n ≤ 30000).
Line 2: n numbers a1, a2, …, an (1 ≤ ai ≤ 106).
Line 3: q (1 ≤ q ≤ 200000), the number of d-queries.
In the next q lines, each line contains 2 numbers i, j representing a d-query (1 ≤ i ≤ j ≤ n).
Output
For each d-query (i, j), print the number of distinct elements in the subsequence ai, ai+1, …, aj in a single line.
Example
Input
5
1 1 2 1 3
3
1 5
2 4
3 5
Output
3
2
3
分析: 理解了莫队算法,这个就很轻松了
这里的数据范围很小,如果很大可能要用到离散化处理一下。
时间复杂度o((M+N) *sqr(N))
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 3e4+11;
const int M = 200000+11;
const int MAX = 1e6+11;
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;
const int inff = 0x3f3f3f3f3f3f3f3f;
int B;
struct Query{
int le,ri;
int id;
bool operator < (const Query &b) const {
if( le/ B == b.le / B) return ri < b.ri;
else return le/ B < b.le / B;
}
}Q[M]; int ANS[M];
int cnt[MAX]; int a[N]; int ans;
void Add(int x){
x=a[x];
if(cnt[x]==0) ans++;
cnt[x]++;
}
void Del(int x){
x=a[x];
cnt[x]--;
if(cnt[x]==0) ans--;
}
void solve(int q){
sort(Q+1,Q+q+1);
memset(cnt,0,sizeof(cnt));
int L=1,R=0; ans=0;
for(int i=1;i<=q;i++){
while(R<Q[i].ri) Add(++R) ;
while(R>Q[i].ri) Del(R--);
while(L<Q[i].le) Del(L++);
while(L>Q[i].le) Add(--L);
ANS[Q[i].id]=ans;
}
for(int i=1;i<=q;i++) printf("%d\n",ANS[i]);
}
int main(){
int n;scanf("%d",&n); B=(int)sqrt(n*1.0);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
int q;scanf("%d",&q);
for(int i=1;i<=q;i++){
scanf("%d%d",&Q[i].le,&Q[i].ri);
Q[i].id=i;
}
solve(q);
return 0;
}