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相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义 ...
随机推荐
- hadoop报错java.io.IOException: Incorrect configuration: namenode address dfs.namenode.servicerpc-address or dfs.namenode.rpc-address is not configured
不多说,直接上干货! 问题详情 问题排查 spark@master:~/app/hadoop$ sbin/start-all.sh This script is Deprecated. Instead ...
- python去掉括号之间的字符
在字符串中识别括号并删除括号及其中的内容括号包括 大中小 3种括号 输入为 1个字符串 s="我是一个人(中国人)[真的]{确定}"; 输出为 result = "我是一 ...
- to_date() 、to_char()、to_number的FMT格式
元素 含义 结果:2018/01/12(周五) - / , . ; : (6中不同分隔符) 分隔符 y 显示一位年份 8 yy 显示二位年 ...
- css代码结构
整个文档结构如下: 一般性样式 主体样式 reset样式 链接 标题 其他元素 辅助样式 表单 通知和错误 一致的条目 页面结构 标题.页脚和导航 布局 其他页面结构元素 页面组件 各个页面 覆盖
- android中finish和system.exit方法退出的区别
finish只是将此activity推向后台,并没有释放资源. 而system.exit则是杀死进程,会释放资源
- MyBatis配置Setting详细说明
该表格转载自http://blog.csdn.net/summer_yuxia/article/details/53169227 setting是指定MyBatis的一些全局配置属性,这是MyBati ...
- git在eclipse中的配置 完整版 转载
http://www.cnblogs.com/zhxiaomiao/archive/2013/05/16/3081148.html
- oracle错误汇总解决
1.ORA-12514 http://blog.sina.com.cn/s/blog_5007d1b10100oqo8.html
- hive的not in
最近项目需要对数据做打平操作,原有的sql使用了not in,但是hive 不支持 not in,晚上搜索了下使用 left outer join select * from lefttbl a le ...
- Bootstrap 的 Tooltip 和 Popover
简介 Tooltip 指提示框,Popover 指弹出框. Tooltip 默认 Tooltip 功能是关闭的,使用前要手动开启. $(function () { $('[data-toggle=&q ...