C91 树状数组+排序 P1972 [SDOI2009] HH的项链
视频链接:C91 树状数组+排序 P1972 [SDOI2009] HH的项链_哔哩哔哩_bilibili
C35 线段树+排序 P1972 [SDOI2009] HH的项链 - 董晓 - 博客园 (cnblogs.com)
C52 可持久化线段树 P1972 [SDOI2009] HH的项链 - 董晓 - 博客园 (cnblogs.com)
// 树状数组+排序 O(nlogn) #include <iostream> #include <cstring> #include <algorithm> using namespace std; void read(int &x){ x=0; char c=getchar(); while(c<'0'||c>'9') c=getchar(); while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); } #define N 1000010 #define lowb(x) x&-x int n,m; int a[N],last[N],ans[N]; int s[N]; //区间内1的个数 struct Q{ int l,r,id; //查询的区间端点,查询的编号 bool operator<(const Q& b)const{ return r<b.r; } }q[N]; void change(int x,int k){ //向后修 while(x<=n) s[x]+=k, x+=lowb(x); } int query(int x){ //向前查 int t=0; while(x) t+=s[x], x-=lowb(x); return t; } 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); //查询按右端点排序 for(int i=1,lp=1;i<=m;++i){ //枚举每个查询 for(int j=lp;j<=q[i].r;++j){ //枚举右端点前面的位置 if(last[a[j]]) change(last[a[j]],-1); //aj上次位置-1 change(j,1); //aj这次的位置+1 last[a[j]]=j; //记录aj这次的位置 } lp=q[i].r+1; //更新已处理位置的左边界 ans[q[i].id]=query(q[i].r)-query(q[i].l-1); //记录答案 } for(int i=1;i<=m;++i) printf("%d\n",ans[i]); }
分类:
C 数据结构
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!