区间种类数问题

例题

1|0在线做法

利用可持久化线段树,从左至右依次扫一遍,因为我们只关心种类,故只需要保留最靠右的那一个数即可,其它的没用。查询时调用 rootr 所在的线段树。具体的,首先在下标 i1,找到前一个值为 ai 的下标 posai,将其减 1,最后 posai=i,这样就只保留最靠右的那一个数。查询时调用 rootr 的原因是:这颗线段树保留的是 [1,r] 最靠右的数,无论 l 取到什么,sum[l,r] 都是区间种类数。

const int N=1e6+7; int n,a[N],pos[N],root[N],tot; struct Tree{ int sum[N*40],ls[N*40],rs[N*40]; void pushup(int p){sum[p]=sum[ls[p]]+sum[rs[p]];} void modify(int q,int &p,int x,int k,int l=1,int r=n){ p=++tot; ls[p]=ls[q];rs[p]=rs[q];sum[p]=sum[q]; if(l==r){sum[p]+=k;return;} int mid=l+r>>1; if(x<=mid)modify(ls[q],ls[p],x,k,l,mid); else modify(rs[q],rs[p],x,k,mid+1,r); pushup(p); } int query(int p,int ql,int qr,int l=1,int r=n){ if(ql<=l&&r<=qr)return sum[p]; int mid=l+r>>1,ans=0; if(ql<=mid)ans+=query(ls[p],ql,qr,l,mid); if(qr>mid)ans+=query(rs[p],ql,qr,mid+1,r); return ans; } }tr; int main(){ read(n); for(int i=1;i<=n;i++)read(a[i]); for(int i=1;i<=n;i++){ tr.modify(root[i-1],root[i],i,1); if(pos[a[i]])tr.modify(root[i],root[i],pos[a[i]],-1); pos[a[i]]=i; } int q;read(q); while(q--){ int l,r; read(l);read(r); printf("%d\n",tr.query(root[r],l,r)); } return 0; }

2|0离线做法

树状数组做法类似可持久化线段树,只不过是将询问按 r 排序,然后从小到大处理,就不必可持久化。

const int N=1e6+7; int m,n,a[N],pos[N],c[N],ans[N]; struct bb{ int l,r,id; bool operator<(const bb t)const{ return r<t.r; } }q[N]; int lowbit(int x){return x&(-x);} void add(int x,int y){while(x<=n)c[x]+=y,x+=lowbit(x);} int query(int x){int s=0;while(x)s+=c[x],x-=lowbit(x);return s;} int main(){ read(n); for(int i=1;i<=n;i++)read(a[i]); read(m); for(int i=1;i<=m;i++) read(q[i].l),read(q[i].r),q[i].id=i; sort(q+1,q+m+1); int r=0; for(int i=1;i<=m;i++){ while(r<q[i].r){ r++;add(r,1); if(pos[a[r]])add(pos[a[r]],-1); pos[a[r]]=r; } ans[q[i].id]=query(r)-query(q[i].l-1); } for(int i=1;i<=m;i++) printf("%d\n",ans[i]); return 0; }

莫队做法这题就是板题,可以在我的 这篇博客 里查看。


__EOF__

本文作者JMartin
本文链接https://www.cnblogs.com/LAK666/p/Number_of_interval_categories.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Epoch_L  阅读(117)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示