HH的项链—树状数组

题目描述
HH有一串由各种漂亮的贝壳组成的项链。HH相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义。
HH不断地收集新的贝壳,因此他的项链变得越来越长。有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同的贝壳?
这个问题很难回答。。。因为项链实在是太长了。于是,他只好求助睿智的你,来解决这个问题。
输入格式
第一行:一个整数N,表示项链的长度。
第二行:N个整数,表示依次表示项链中贝壳的编号(编号为01000000之间的整数)。
第三行:一个整数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#

posted @   __kw  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示