实际上这题很难和树状数组联系起来,我感觉效率也不是很高,感觉不是正解

怎么使用树状数组

这道题我们很容易想到一点:同种物品在一个区间内只能出现一次,先不考虑别的问题,我们想出下面这种使用树状数组的思路:

  • 定义树状数组只有 \(0\) 和 \(1\) 两种状态,分别表示统计这个物品或不统计这个物品.
  • 从前往后统计物品,即遍历赋值 \(1\) .
  • 记录上一个和当前物品种类相同的物品在哪里,假如我们统计了当前物品,就把上一个相同种类的物品置 \(0\) .
  • 区间 \([i,j]\) 内的物品种类数即为 \(sum(i,j)\).

但是这样做有一个问题,假如上一个相同种类的物品在区间内,但是当前这一个不在. 那么我们统计时,这个物品种类已经置 \(0\) , 就会出现错误.

离线

综上,我们现在需要解决一个问题:

统计当前区间时,这个区间内的物品既不能未统计,也不能已置 \(0\) .

我们可以这样解决:

  • 记录每个区间的右端点,并从小到大排序.
  • 取出一个最小的右端点,若当前对物品的遍历到达了这个右端点,那么马上算出答案并存储.
  • 重复上述步骤.

这样一来,因为置 \(0\) 影响到的区间已经被事先算出来了,所以丝毫没有受到影响.

事实上,我们用到了一种算法思想即离线算法:先存储所有问题,待全部询问结束后再全部输出.

细节处理

1. 关于区间遍历

我们可以开一个变量 \(now\) 作为指针来记录当前遍历到的区间,若答案被算出,则 \(now++\) . 考虑到有右端点重复的区间,因此我们的写法如下:

while(a[now].r==i){
算出答案并存储;
now++;
}

2. 关于答案存储

我们可以给区间开一个结构体,这个结构体里除了有区间的左右端点之外,还有一个区间的询问顺序编号. 按这个编号,我们可以做到有序输出.

代码实现

注:本代码使用 封装树状数组

BIT t;
int s[1000001],fore[1000001],ans[1000001]; //s为原序列,fore记录了上一个相同种类的序号,ans记录答案
struct area{
int l,r,id;
bool operator <(const area &A)const{
return r<A.r;
}
}a[1000001];//记录区间
int n,anow=1,m;
int main(){
cin>>n;
t.n=n;
for(int i=1;i<=n;++i){
cin>>s[i];
}
cin>>m;
for(int i=1;i<=m;++i){
cin>>a[i].l>>a[i].r;
a[i].id=i;
}
sort(a+1,a+m+1);
for(int i=1;anow<=m&&i<=n;++i){
t.change(i,1);
if(fore[s[i]]){
t.change(fore[s[i]],-1);
}
fore[s[i]]=i;
while(a[anow].r==i){
ans[a[anow].id]=t.sum(a[anow].l,a[anow].r);
anow++;
}
}
for(int i=1;i<=m;++i){
cout<<ans[i]<<endl;
}
}

[TK] HH的项链 离线树状数组解法的更多相关文章

  1. P1972 [SDOI2009]HH的项链[离线+树状数组/主席树/分块/模拟]

    题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不断地收集新的贝壳,因此,他的项链 ...

  2. BZOJ 1878: [SDOI2009]HH的项链 离线树状数组

    1878: [SDOI2009]HH的项链 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...

  3. 【洛谷P1972】HH的项链 离线+树状数组

    题目大意:静态查询序列区间颜色数. 题解:对于一个查询区间 [l , r] ,若有两个相同颜色的点在这个区间中,则总是取下标靠近端点 r 的颜色计入答案贡献.对于每个下标,记录下在这个下标之前,且距离 ...

  4. 洛谷 P1972 [SDOI2009]HH的项链(树状数组,离线)

    传送门 解题思路 因为是求区间的不同种类数,所以我们用树状数组(貌似并没有什么直接联系) (...表示到) 还是和原来一样,用s[i]来表示a[i-lowbit(i)]...a[i]的种类数. 因为有 ...

  5. 【BZOJ】1878: [SDOI2009]HH的项链(树状数组)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1878 我太弱了,看题解才过的. 一开始看到此题,我想了想在线做法,但之后觉得这个想法可能是错的:维护 ...

  6. 洛谷P1972 [SDOI2009]HH的项链(树状数组)

    题目链接: https://www.luogu.org/problemnew/show/P1972 题目描述: HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后 ...

  7. bzoj 1878: [SDOI2009]HH的项链【树状数组】

    对于一个lr,每个颜色贡献的是在(1,r)区间里出现的最右位置,所以记录一个b数组表示当前点这个颜色上一个出现的位置 然后把询问离线,按r升序排序 每次把右端点右移,把这个点在树状数组上+1,并且在当 ...

  8. [BZOJ1878][SDOI2009] HH的项链 (树状数组)

    link 一道简单题. 不用可持久化. 对于统计颜色个数,可以看与其颜色一样的前一个位置. 设$las(i)$表示其与$i$颜色相等的上一个位置. 则对于二元组$(l,r)$,其答案为$\sum_{i ...

  9. [bzoj1878][SDOI2009]HH的项链_树状数组

    HH的项链 bzoj-1878 SDOI-2009 题目大意:给定一个n个数的序列,m次查询.查询区间数的种类个数. 注释:$1\le n \le 5\cdot 10^4$,$1\le m\le 2\ ...

  10. BZOJ 1878 HH的项链(树状数组)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1878 题意:给出一个数列,每次询问区间[L,R]中有多少个不同的数字? 思路: (1)记 ...

随机推荐

  1. JavaScript高级~数组偏平化

    方式一: let arr=[11,[22,[33,[44]]],[55,66,77],88,99,['00']] let arr2=arr.toString().split("," ...

  2. python对象之间的交互

    python对象之间的交互 先看看一般的类定义如下: class 类名: def __init__(self,参数1,参数2): self.对象的属性1 = 参数1 self.对象的属性2 = 参数2 ...

  3. 【H5】04 建立超链接

    摘自: https://developer.mozilla.org/zh-CN/docs/Learn/HTML/Introduction_to_HTML/Creating_hyperlinks 超链接 ...

  4. 【Java】JDBC Part4 Transaction 事务

    JDBC Part4 Transaction 事务 什么是事务? 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消. 也就是原子性,一个事务中的一系列的 ...

  5. 【C】Re03

    一.变量 变量存储了两个东西: 1.内存空间地址 2.内存空间存放的值 本质是给内存地址起了一个别名,允许我们通过别名对内存进行访问 void variable01() { int a = 100; ...

  6. 【Spring Data JPA】07 Specifications动态查询

    [前言说明] 针对CRUD种的查询,因为我们的查询总是具有各种各样的筛选条件 为了我们的程序能够更加适应筛选条件的变化,SpringDataJpa提供了Specifications这种解决方案 Spe ...

  7. nvidia显卡的售后真的是不敢要人恭维——拆机箱时误拧显卡自身挡板螺丝被拒保

    事情比较简单,单位在nvidia的经销商那里购买的nvidia titan rtx显卡,保修期内坏掉,拆下来的过程中误拧了挡板的螺丝,结果被拒保,这里就是单纯的记录这件事情. 这件事确实我这方面有不对 ...

  8. Functional PHP (通义千问)

    Functional PHP 是一个专为 PHP 开发者设计的库,旨在引入函数式编程的概念和工具,帮助开发者编写更高效.可读性强的代码.以下是几个使用 Functional PHP 库进行函数式编程的 ...

  9. 系统IO常用函数接口

    本文整理归纳了几种常用的系统IO的函数借口,以供读者查阅使用 目录 系统IO与标准IO的区别 打开文件:open 关闭文件:close 文件读取:read 文件写入:write 位置偏移:lseek ...

  10. CentOS 进入救援模式

    因某些修改操作,导致系统重启后无法正常启动,此时需要进入救援模式,修复错误配置即可. 1.重启系统后,进入grup引导页面,选中第一项然后按"e" 进入编辑模式: 2.通过↓键找到 ...