嗯。就是把分块先预处理出来。 怎么会事呢?
#include<bits/stdc++.h>
using namespace std;
int n , m ;
int K ;
int w[10000001];
int Block[10000001];
int cnt[10000001];
struct Node{
int id , l , r;
}a[1000000];
int ans[1000001];
bool Mycmp(const Node &a , const Node &b){
int i = Block[a.l];
int j = Block[b.l];
if(i != j) return i < j;
return a.r < b.r;
}
void add(int x,int &res){
if(!cnt[x]) res++;
cnt[x] ++;
}
void del(int x,int &res){
cnt[x] --;
if(!cnt[x]) res--;
}
int main(){
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n;
m = sqrt(n);
for(int i = 1 ; i <= n ; i ++){
cin >> w[i];
Block[i] = (i - 1) / m + 1;
}
cin >> K;
for(int i = 0 ; i < K ; i++){
int l , r;
cin >> l >> r;
a[i].id = i;
a[i].l = l;
a[i].r = r;
}
sort(a , a + K, Mycmp);
for(int k = 0 , i = 0 , j = 1 , res = 0 ; k < K ; k ++){
int id = a[k].id;
int l = a[k].l;
int r = a[k].r;
while(i < r) add(w[++i] , res);
while(i > r) del(w[i--] , res);
while(j < l) del(w[j++] , res);
while(j > l) add(w[--j] , res);
ans[id] = res;
}
for(int i = 0 ; i < K ; i++) cout << ans[i] <<endl;
return 0;
}