版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sugar_free_mint/article/details/88364647
题目
问区间中数的种类
分析
那么由于这道题没有修改,所以可以用树状数组离线回答,对于左区间排序,然后用树状数组统计
代码
#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
struct rec{int l,r,rk;}b[500001];
int n,m,ans[500001],a[500001],c[500001],pos[1000001];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
bool cmp(rec t1,rec t2){return t1.r<t2.r;}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
inline void add(int x,int y){
while (x<=n){
c[x]+=y;
x+=-x&x;
}
}
inline signed answ(int x){
rr int ans=0;
while (x){
ans+=c[x];
x-=-x&x;
}
return ans;
}
signed main(){
n=iut(); for (rr int i=1;i<=n;++i) a[i]=iut();
m=iut(); for (rr int i=1;i<=m;++i) b[i]=(rec){iut(),iut(),i};
sort(b+1,b+1+m,cmp); rr int now=1;
for (rr int i=1;i<=m;++i){
for (rr int j=now;j<=b[i].r;++j){
if (pos[a[j]]) add(pos[a[j]],-1);
add(pos[a[j]]=j,1);
}
now=b[i].r+1;
ans[b[i].rk]=answ(b[i].r)-answ(b[i].l-1);
}
for (rr int i=1;i<=m;++i) print(ans[i]),putchar(10);
return 0;
}