传送门

主席树解法
设las[ i ]表示数列中第 i 个数的值 上一次出现的位置,num[ i ]为原数列中第 i 个数的值
1. 把 从第 1 到第 i 个数的 las 的值  的出现次数 建立一个线段树
那么第 i 个叶子节点 i 就表示 las 值为 i-1 的出现次数
对于序列 1 2 1 3 4 1 建立的线段树如图:

2. 一共有 n 个线段树,合在一起就是主席树(要对每个 i 建立线段树)

3. 询问 l,r 就只要把第 r 个线段树中从 0 到 l-1 的值的和 减去第 l-1 个个线段树从 0 到 l-1 的值的和。


关于第3点的证明:
想一想,对于同一个 i , 第 r 个线段树的叶子节点 i 减去第 l-1 个线段树的叶子节点 i 的值( i 从 0 到 l-1) 就表示从 l~r 区间多出了的   区间  l~r (注意是从 l 到 r ) 中第一次出现的数字 a (a 为 num[ i ])的数量(多出的数量为 1 或 0,除非 i 等于 0)

因为如果区间 l~r 中第 j 个数 a 再次出现(再次出现意思是数列 l~r 中已经有出现过 a 了),那么las[ j ]就为 区间l~r 中 的前面同一个数 a 的位置(显然 l<= las[ j ] <= r),不会更新叶子节点i的值(因为 0<= i <= l-1),因此可以把叶子节点的值拿来相减,既然叶子可以相减,那么它们的父节点也能相减.


思路懂了就不难了..

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const int N=;
int n,m,cnt;
int las[N],pre[N]; //------以下为主席树------ int rt[N],L[N<<],R[N<<],sum[N<<];
inline int build(int pre,int l,int r,int v)
{
int root=++cnt; sum[root]=sum[pre]+;
if(l==r) return root;
L[root]=L[pre]; R[root]=R[pre];
int mid=(l+r)>>;
if(v<=mid) L[root]=build(L[pre],l,mid,v);
else R[root]=build(R[pre],mid+,r,v);
return root;
}
inline int query(int hea,int las,int l,int r,int ql)
{
if(r<=ql) return sum[las]-sum[hea];
int mid=(l+r)>>;
int res=query(L[hea],L[las],l,mid,ql);
return mid>=ql ? res : res+query(R[hea],R[las],mid+,r,ql);
} //------以上为主席树------ int main()
{
int a;
cin>>n;
for(int i=;i<=n;i++)
{
scanf("%d",&a);
las[i]=pre[a];
pre[a]=i;
}
for(int i=;i<=n;i++)
rt[i]=build(rt[i-],,n,las[i]);//注意l从0开始
cin>>m;
int l,r;
while(m--)
{
scanf("%d%d",&l,&r);
printf("%d\n",query(rt[l-],rt[r],,n,l-));//注意l从0开始
}
return ;
}

1972 HH的项链的更多相关文章

  1. BZOJ1878 洛谷1972 HH的项链题解

    洛谷链接 BZOJ链接 看到这样不用修改的题目,应该佷容易就联想到了离线来处理. 我们发现若将询问按照r来排序,排完后每次对答案有贡献的仅是每个颜色最后出现的位置 我们用next[i]表示i处颜色之前 ...

  2. 洛谷1972 HH的项链 树状数组查询区间内不同的数的数量

    题目链接:https://www.luogu.com.cn/problem/P1972 题意大致是:给定一个序列长度为n,给出m个查询区间,要求响应是区间内不同的数的个数.为此我们考虑到树状数组的区间 ...

  3. Codevs 2307[SDOI2009]HH的项链

    同题:     Codevs 2307 HH的项链     BZOJ    1878 HH的项链     洛谷      1972 HH的项链 2009年省队选拔赛山东  时间限制: 1 s  空间限 ...

  4. 【洛谷】1972:[SDOI2009]HH的项链【莫队+树状数组】

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

  5. 洛谷 P1972 [SDOI2009]HH的项链【莫队算法学习】

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

  6. BZOJ 1878: [SDOI2009]HH的项链

    1878: [SDOI2009]HH的项链 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 3548  Solved: 1757[Submit][Statu ...

  7. BZOJ-1878 HH的项链 树状数组+莫队(离线处理)

    1878: [SDOI2009]HH的项链 Time Limit: 4 Sec Memory Limit: 64 MB Submit: 2701 Solved: 1355 [Submit][Statu ...

  8. 【BZOJ】【1878】【SDOI2009】HH的项链

    树状数组/前缀和 Orz lct1999 好神的做法... 先看下暴力的做法:对于区间[l,r],我们依次扫过去,如果这个数是第一次出现,那么我们种类数+1. 我们发现:区间中相同的几个数,只有最左边 ...

  9. 【BZOJ1878】[SDOI2009]HH的项链 离线BIT

    1878: [SDOI2009]HH的项链 Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义 ...

随机推荐

  1. -bash : ** : command not found的问题解决(图文详解)

    问题来源 我不小心,配置错了,少了个export和PATH没配对.   source /etc/profile 之前一定要留心,否则出错让你后悔去! 问题导致现象1 问题导致现象2 解决办法 按e键, ...

  2. 剑指offer 38_统计数组中k出现的个数

    思路: 二分法,分别找出第一个和最后一个k出现的位置.相减 加一 #include <stdio.h> //获取第一个K的位置 int getFirstK (int k,int *numb ...

  3. 进程与进程之间通信Manager

    #!/usr/bin/env python from multiprocessing import Process,Manager #Manager进程与进程之间通信 def Foo(i,dic): ...

  4. matlab基础功能实践

    一.matlab在高等数学中的应用(<数学建模算法与应用>P453) 1.求极限 syms x b=limit((sqrt(1+x^2)-1)/(1-cos(x))) syms x a b ...

  5. gearman 并发的执行多个任务

    Examples: Multi-Query In this example we know that we need to fetch several result sets from a datab ...

  6. 算法Sedgewick第四版-第1章基础-2.1Elementary Sortss-001选择排序法(Selection sort)

    一.介绍 1.算法的时间和空间间复杂度 2.特点 Running time is insensitive to input. The process of finding the smallest i ...

  7. Linux tput命令

    一.简介 shell 脚本编写者往往需要能通过一种方法将输出更改为粗体,为其加下划线,实现反向突出显示等,这正是 tput 的用武之地. tput 命令将通过 terminfo 数据库对您的终端会话进 ...

  8. NCBI下载SRA数据

    从NCBI下载数据本来是一件很简单的事情,但是今天碰到几个坑: 1.paper里没有提供SRA数据号.也没有提供路径: 2.不知道文件在ftp的地址,不能直接用wget下载 所以通过在NCBI官网,直 ...

  9. ZROI2018提高day3t3

    传送门 分析 我们对于每一个可以匹配的字符都将其从栈中弹出,然后他的哈希值就是现在栈中的字符哈希一下.然后我们便可以求出对于哪些位置它们的哈希值是一样的,即它们的状态是一致的.而这些点可以求出它们的贡 ...

  10. Mat 与 IplImage 和 CvMat 的转换

    在 OpenCV 2 中虽然引入了方便的 Mat 类,出于兼容性的考虑,OpenCV 依然是支持 C 语言接口的 IplImage 和 CvMat 结构.如果你要与以前的代码兼容,将会涉及 Mat 与 ...