区间内有多少个不同的数字(离线树状数组)

来源:互联网 发布:医疗大数据解决方案 编辑:程序博客网 时间:2024/05/16 06:56

知道了区间的两个端点s和e,那么这个区间内有多少个不同的数字

先把询问存一起  按右端点排个序  每次用map看出没出现过 一直保留最后出现的那个 再算出所有查询。。

#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<map>using namespace std;#define clr(x) memset(x,0,sizeof(x))#define INF 0x1f1f1f1fstruct node {    int st,en,id,ans;}q[100010];int cmp(struct node a,struct node b){    return a.en<b.en;}int cmp1 (struct node a,struct node b){    return a.id<b.id;}int cal[100010];int lowbit(int x) {return x&(-x);}int getsum(int x){    int s=0;    for(;x>0;x-=lowbit(x)) s+=cal[x];    return s;}void update(int x,int value){    for(;x<=100010;x+=lowbit(x)) cal[x]+=value;}int n,Q;int a[100010];int main(){    map<int,int>mp;    int i;    while(scanf("%d%d",&n,&Q)!=EOF){        mp.clear();        clr(cal);        for(i=1;i<=n;i++){            scanf("%d",&a[i]);        }        for(i=1;i<=Q;i++){            scanf("%d%d",&q[i].st,&q[i].en);            q[i].id=i;        }        sort(q+1,q+Q+1,cmp);        int temp=1;        for(i=1;i<=Q;i++){                while(temp<=q[i].en){                    if(mp[a[temp]]!=0){                        update(mp[a[temp]],-1);                    }                    mp[a[temp]]=temp;                    update(temp,1);                    temp++;                }                q[i].ans=getsum(q[i].en)-getsum(q[i].st-1);        }        sort(q+1,q+1+Q,cmp1);        for(i=1;i<=Q;i++){            printf("%d\n",q[i].ans);        }    }    return 0;}


原创粉丝点击