求区间不同数的个数。用离线处理,按右端点排序。出现相同的个数,那么靠右端点的才有权值,前面的权值都为0.
可以直接主席树搞(TLE两点).
代码
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6 + 10;
int n,m;
int c[N],a[N];
int last[N],pos[N],ans[N];
struct Node{
int l,r,id;
bool operator < (const Node&T)const{
return r < T.r;
}
}node[N];
#define lowbit(x) ((x) & (-x))
void update(int x,int y){
for(int i=x;i<=n;i+=lowbit(i)) c[i] += y;
}
int query(int x){
int sum = 0;
for(int i=x;i;i-=lowbit(i)) sum += c[i];
return sum;
}
signed main(){
IOS
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++){
pos[i] = last[a[i]];
last[a[i]] = i;
}
cin>>m;
for(int i=1;i<=m;i++){
cin>>node[i].l>>node[i].r;
node[i].id = i;
}
sort(node+1,node+m+1);
for(int i=1,j=1;i<=m;i++){
int l = node[i].l,r = node[i].r,id = node[i].id;
while(j <= r){
if(pos[j] != 0) update(pos[j],-1);
update(j,1);
j ++;
}
ans[id] = query(r) - query(l - 1);
}
for(int i=1;i<=m;i++) cout<<ans[i]<<endl;
return 0;
}