C92 树状数组+排序 P4113 [HEOI2012] 采花
视频链接:C92 树状数组+排序 P4113 [HEOI2012] 采花_哔哩哔哩_bilibili
// 树状数组+排序 O(nlogn) #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define N 2000010 #define lowb(x) x&-x int n,c,m,a[N],pos1[N],pos2[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(){ scanf("%d%d%d",&n,&c,&m); for(int i=1;i<=n;++i)scanf("%d",&a[i]); for(int i=1;i<=m;++i) scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i; sort(q+1,q+m+1); //查询按右端点排序 for(int i=1,j=1;i<=m;++i){ //枚举每个查询 for(;j<=q[i].r;++j){ //枚举r前面的位置 if(!pos1[a[j]]) //若aj第1次位置为空 pos1[a[j]]=j; //记录aj第1次出现位置 else{ //若aj第1次位置不空 if(!pos2[a[j]]){ //若aj第2次位置为空 change(pos1[a[j]],1); //aj第1次出现位置+1 pos2[a[j]]=j; //记录aj第2次出现位置 } else{ //若aj第2次位置不空 change(pos1[a[j]],-1); //aj第1次出现位置清空 change(pos2[a[j]],1); //aj第2次出现位置+1 pos1[a[j]]=pos2[a[j]]; //第2次位置变成第1次 pos2[a[j]]=j; //当前位置变成第2次 } } } 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框架的用法!