HH的项链—树状数组
题目描述 HH有一串由各种漂亮的贝壳组成的项链。HH相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义。 HH不断地收集新的贝壳,因此他的项链变得越来越长。有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同的贝壳? 这个问题很难回答。。。因为项链实在是太长了。于是,他只好求助睿智的你,来解决这个问题。 输入格式 第一行:一个整数N,表示项链的长度。 第二行:N个整数,表示依次表示项链中贝壳的编号(编号为0到1000000之间的整数)。 第三行:一个整数M,表示HH询问的个数。 接下来M行:每行两个整数,L和R(1 ≤ L ≤ R ≤ N),表示询问的区间。 输出格式 M行,每行一个整数,依次表示询问对应的答案。 样例 样例输入 6 1 2 3 4 3 5 3 1 2 3 5 2 6 样例输出 2 2 4 数据范围与提示 N ≤ 50000,M ≤ 200000。
思路:
我做这道题的思路是树状数组+排序(只因博主没学过莫队),首先记录下每种贝壳的下一种不同贝壳所在的位置,将所有询问按照右端点进行排序。从左往右遍历,扫过一个元素就将该位置++,若有前驱,再将前驱--。遍历到区间端点答案为getsum[r]-getsum[l-1](getsum为前缀和)。
还有一点,本题的数据范围真的假,范围给到20万,样例中早已经超过这个范围,所以博主在REn次后才得出要开到100万才行(好好好,故意多给几个RE是吧)。
蒟蒻の代码:
#include <bits/stdc++.h> using namespace std; const int N=1000000; int n,m,vis[N],c[N],a[N],ans[N]; struct node{ int l,r,num; }s[N]; bool cmp(node a,node b){ return (a.r<b.r||(a.r==b.r&&a.l<b.l)); } int lowbit(const int x){ return x&-x; } void add(int x,int key){ while(x<=n){ c[x]+=key; x+=lowbit(x); } } int getsum(int x){ int s=0; while(x>0){ s+=c[x]; x-=lowbit(x); } return s; } int main(){ int i,j; cin>>n; for(i=1;i<=n;i++) cin>>a[i]; cin>>m; for(i=1;i<=m;i++){ cin>>s[i].l>>s[i].r; s[i].num=i; } sort(s+1,s+1+m,cmp); j=1; for(i=1;i<=n+1;i++){ while(j<=m&&i>s[j].r){ ans[s[j].num]=getsum(s[j].r)-getsum(s[j].l-1); j++; } if(i>n) break; if(vis[a[i]]){ add(vis[a[i]],-1); vis[a[i]]=i; add(i,1); }else{ vis[a[i]]=i; add(i,1); } } for(int i=1;i<=m;i++) cout<<ans[i]<<endl; return 0; }
如有错误,欢迎大佬指正~
#一名爱打篮球的oier#
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】