给定一个序列 ,有 个询问 ,问在该区间中不同数的数量有多少。该题目可以和 ABC371E 对比着做。
,暴力枚举是 的会超时。
但是我们先假定这 个数字本就两两不同,那么他们各自都会产生 的贡献,如果每个数相应的位置都代表数值 ,那么就是在查询 而已。
事实上上述假设并不能一定成立。
那么有一种和莫队和相似的巧妙算法就是先离线,然后再考虑区间之间移动时的增量。
我们先按照右区间升序排序。
言下之意就是如果有 个 ,那你也只能算一种。我们保留刚刚的前缀和算法,钦定所有相同数字 所产生的贡献 都在当前最右边的 身上,其余的 贡献都为 ,并且随着我们枚举区间不断更新这个"最右"的位置,这时候我们发现了按照右区间升序排序的优越性。
那就是下一个枚举到的区间要不就不包含 这个数字 ,要么就一定至少包含最右边的 (可能同时包含左边的 ),由于 是逐渐增大的,所以我们不可能枚举到一个包含左边 们,但又不包含最右边 的区间。因此我们就成功统计了 对当前区间 (如果有的话)的贡献。
所以对于一个 ,我们先做好从上一个 到这一个 的更新,再直接统计答案 就好了。
由于是单点修改并且多次查询,就选择树状数组了。
| #include<bits/stdc++.h> |
| using namespace std; |
| template<typename T>inline void re(T &x) |
| { |
| x=0;int f=1;char c=getchar(); |
| while(!isdigit(c)){if(c=='-')f=-1;c=getchar();} |
| while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();} |
| x*=f; |
| } |
| template<typename T>inline void wr(T x) |
| { |
| if(x<0)putchar('-'),x=-x; |
| if(x>9)wr(x/10); |
| putchar(x%10^48); |
| } |
| const int N=1e6+5; |
| int v[N],c[N],n,m; |
| inline int lowbit(int x){return x&(-x);} |
| inline void add(int x,int v) |
| { |
| for(;x<=n;x+=lowbit(x)) |
| c[x]+=v; |
| } |
| inline int query(int x){int ans=0;for(;x>=1;x-=lowbit(x))ans+=c[x];return ans;} |
| struct Q |
| { |
| int l,r,idx; |
| }a[N]; |
| int ans[N]; |
| bool cmp(Q a,Q b){return a.r==b.r?a.l>b.l:a.r<b.r;} |
| inline void pre() |
| { |
| re(n); |
| for(register int i=1;i<=n;++i)re(v[i]); |
| re(m); |
| for(register int i=1;i<=m;++i) |
| { |
| re(a[i].l),re(a[i].r); |
| a[i].idx=i; |
| } |
| sort(a+1,a+m+1,cmp); |
| } |
| int las[N]; |
| inline void solve() |
| { |
| int st=1; |
| for(int i=1;i<=m;++i) |
| { |
| for(;st<=a[i].r;++st) |
| { |
| if(las[v[st]])add(las[v[st]],-1); |
| add(st,1); |
| las[v[st]]=st; |
| } |
| ans[a[i].idx]=query(a[i].r)-query(a[i].l-1); |
| } |
| } |
| int main() |
| { |
| pre(); |
| solve(); |
| for(register int i=1;i<=m;++i) |
| wr(ans[i]),putchar('\n'); |
| return 0; |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效