题目链接

  难题,所以会讲得细一些。

  首先我们想如何统计区间[l,r]内不同贝壳的个数。

  第一个思路就是线段树/树状数组,query(1,r)-query(1,l-1)对不对?

  然而这样是不对的。

  然后我们举个例子:

  例如有一段区间是[ 1 2 3 1 2 3 1 2 3 ]这样子,如果要统计不同贝壳的个数,那么一个贝壳就可以代表所有同色贝壳。

  也就是说,假设要统计这个区间内1有没有出现,那这个区间变成这样子:[ 1 2 3 0 2 3 0 2 3 ] 或 [ 0 2 3 1 2 3 1 2 3 ] 或什么样子,都是一样的,只要1出现过一次,那就说明1出现过了。

  所以可以把所有询问按左端点排序,左端点相同的按照右端点排序,然后挨个统计:

  设next[ j ] 表示:x为j位置贝壳的颜色,next[j]表示的就是j后面第一个颜色为x的位置。如在我们举的例子中,next[1]=4,next[2]=5,next[5]=8。

  然后我们在刚开始初始化的时候,只有所有颜色第一次出现的位置作为该颜色的代表贝壳,也就是说只有这几个位置有1个不同的贝壳。

  然后在扫描询问数组的时候,把q[i-1].l到q[i].l之间的不同贝壳个数更新。具体方法是把next[当前位置]所指向的位置不同的贝壳变成1。

  这样就可以树状数组查询了。

  

#include<cstdio>
#include<cstdlib>
#include<cctype>
#include<cstring>
#include<algorithm> inline long long read(){
long long num=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-;
ch=getchar();
}
while(isdigit(ch)){
num=num*+ch-'';
ch=getchar();
}
return num*f;
} struct line{
int l,r,id,ans;
bool operator <(const line &a)const{
if(l!=a.l) return l<a.l;
return r<a.r;
}
}q[];
bool cmp(line a,line b){ return a.id<b.id; }
int n;
int tree[];
inline void add(int pos){
while(pos<=n){
tree[pos]++;
pos+=pos&(-pos);
}
}
inline int query(int pos){
int ans=;
while(pos){
ans+=tree[pos];
pos-=pos&(-pos);
}
return ans;
} int pre[];
int next[];
int vis[];
int que[]; int main(){
n=read();
for(int i=;i<=n;++i){
que[i]=read();
next[pre[que[i]]]=i;
if(!pre[que[i]]){
add(i);
vis[i]=;
}
pre[que[i]]=i;
}
int m=read();
for(int i=;i<=m;++i) q[i]=(line){read(),read(),i};
std::sort(q+,q+m+);
q[].l=;
for(int i=;i<=m;++i){
if(q[i-].l!=q[i].l)
for(int j=q[i-].l;j<q[i].l;++j)
if(next[j]&&!vis[next[j]]){
vis[next[j]]=;
add(next[j]);
}
q[i].ans=query(q[i].r)-query(q[i].l-);
}
std::sort(q+,q+m+,cmp);
for(int i=;i<=m;++i) printf("%d\n",q[i].ans);
return ;
}

最新文章

  1. Java学习笔记-Math类
  2. 从一个简单的ASP.NET 5站点开启.NET跨平台之旅
  3. oracle dblink的创建方式
  4. Redirecting Console.WriteLine() to Textbox
  5. Swift控制流
  6. Java线程池的实现
  7. 【Python】入门 list有些不懂
  8. JDK源码阅读(三) Collection&lt;T&gt;接口,Iterable&lt;T&gt;接口
  9. [Javascript] Manage Application State with Immutable.js
  10. 一步一步学EF系列 【7、结合IOC ,Repository,UnitOfWork来完成框架的搭建】
  11. Dell7040mt安装win7系统说明
  12. VBS 读取文本文件特殊字符前如逗号的值并赋值给变量
  13. [内存管理]管理图解v0.1 v0.2 v0.3
  14. 0_Simple__cppOverload
  15. 你真的了解webview么?
  16. 第四节,目标检测---YOLO系列
  17. Lua中的环境概念
  18. 设计模式之Factory Method模式
  19. new Random().Next(1, 100); 多线程同时执行结果很高概率相同,
  20. DBProxy

热门文章

  1. Vue实例的4个常用选项
  2. hihoCode r#1077 : RMQ问题再临-线段树
  3. codeforce Gym 100203I I WIN (网络流)
  4. UVA116 Unidirectional TSP 单向TSP
  5. jquery实现跑马灯效果(一)
  6. CPP-基础:关于多态
  7. oracle row_number的使用
  8. CS193p Lecture 6 - UINavigation, UITabBar
  9. passive event 解决方法
  10. 【Office_Word】Word排版