1972 HH的项链
主席树解法
设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的项链的更多相关文章
- BZOJ1878 洛谷1972 HH的项链题解
洛谷链接 BZOJ链接 看到这样不用修改的题目,应该佷容易就联想到了离线来处理. 我们发现若将询问按照r来排序,排完后每次对答案有贡献的仅是每个颜色最后出现的位置 我们用next[i]表示i处颜色之前 ...
- 洛谷1972 HH的项链 树状数组查询区间内不同的数的数量
题目链接:https://www.luogu.com.cn/problem/P1972 题意大致是:给定一个序列长度为n,给出m个查询区间,要求响应是区间内不同的数的个数.为此我们考虑到树状数组的区间 ...
- Codevs 2307[SDOI2009]HH的项链
同题: Codevs 2307 HH的项链 BZOJ 1878 HH的项链 洛谷 1972 HH的项链 2009年省队选拔赛山东 时间限制: 1 s 空间限 ...
- 【洛谷】1972:[SDOI2009]HH的项链【莫队+树状数组】
P1972 [SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含 ...
- 洛谷 P1972 [SDOI2009]HH的项链【莫队算法学习】
P1972 [SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含 ...
- BZOJ 1878: [SDOI2009]HH的项链
1878: [SDOI2009]HH的项链 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 3548 Solved: 1757[Submit][Statu ...
- BZOJ-1878 HH的项链 树状数组+莫队(离线处理)
1878: [SDOI2009]HH的项链 Time Limit: 4 Sec Memory Limit: 64 MB Submit: 2701 Solved: 1355 [Submit][Statu ...
- 【BZOJ】【1878】【SDOI2009】HH的项链
树状数组/前缀和 Orz lct1999 好神的做法... 先看下暴力的做法:对于区间[l,r],我们依次扫过去,如果这个数是第一次出现,那么我们种类数+1. 我们发现:区间中相同的几个数,只有最左边 ...
- 【BZOJ1878】[SDOI2009]HH的项链 离线BIT
1878: [SDOI2009]HH的项链 Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义 ...
随机推荐
- js分页demo
纯js实现分页 原理:所有数据已加载好,js通过遍历部分显示,实现分页效果 html代码 <html> <head> <meta charset='utf-8'> ...
- python+requests+excel 接口测试
1.EXCEL文件接口保存方式,如图. 2.然后就是读取EXCEL文件中的数据方法,如下: import xlrd class readExcel(object): def __init__(self ...
- 剑指offer 34_丑数
丑数:只有2 3 5 这三个因子的数,求前(第)1500个.习惯上我们把1当作第一个丑数 例如 6, 8是丑数.14不是. #include <stdio.h> int Min(int x ...
- elmah数据库sql脚本
/* 错误管理工具 SQL代码 */CREATE TABLE dbo.ELMAH_Error( ErrorId UNIQUEIDENTIFIER NOT NULL, Application NVARC ...
- HTML标签详细讲解
http://www.cnblogs.com/yuanchenqi/articles/5603871.html
- checked多选,取消,反选
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- rm 删除文件或目录
rm命令可以删除一个目录中的一个或多个文件或目录,也可以将某个目录及其下属的所有文件及其子目录均删除掉.对于链接文件,只是删除整个链接文件,而原有文件保持不变. 注意:使用rm命令要格外小心.因为一旦 ...
- 2018 - Start Up
转眼2017已经过去,从大四下学期出来实习,到现在工作一年多了,很遗憾没有经营好自己博客园&CSDN. 献上一篇鼓励工程师写blog的博客:https://kb.cnblogs.com/pag ...
- SpringMVC内容略多 有用 熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器、过滤器等Web组件以及MVC架构模式进行Java Web项目开发的经验。
熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器.过滤器等Web组件以及MVC架构 ...
- R: 常用操作:
################################################### #清除所有变量: rm(list=ls()) #查看变量类型 getwd() setwd() i ...