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相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义 ...
随机推荐
- Android开发国际化
安卓中,国际化十分简单. 其实就是文件夹的问题.一般我们分两种情况. 一是app根据系统语言调用对应的资源文件夹,二是在app里面根据用户的需求来更改语言.前者比较简单,只需求创建对应国家的strin ...
- 一个servlet处理多个请求(使用Method的反射机制)
方法一 可以通过在请求的时候加上参数,然后在servlet中获取请求的参数,再去调用对应的方法.达到一个servlet处理多个请求的目的 test.jsp: <%@ page language= ...
- MyBatis总结二:增删改查
上一篇讲述了MyBatis的快速入门,下面在此基础上进行增删改查的操作: 首先定义dao层的接口: package com.zy.dao; import com.zy.domain.User; imp ...
- 关于mybatis和spring复合pom的异常
java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout()L ...
- Tensorflow 优化学习
# coding: utf-8 import tensorflow as tffrom tensorflow.examples.tutorials.mnist import input_data pr ...
- ZROI2018普转提day2t4
传送门 分析 考场上暴力水过好评... 然后我的st表查询似乎是log的,然后log三方跑的比log方快,qwq. 我们发现如果一个区间的最小值就是这个区间的gcd,则这个区间合法.所以我们二分区间长 ...
- Direct ByteBuffer学习
ByteBuffer有两种一种是heap ByteBuffer,该类对象分配在JVM的堆内存里面,直接由Java虚拟机负责垃圾回收,一种是direct ByteBuffer是通过jni在虚拟机外内存中 ...
- Business Trip to Taian
工作必备 电脑.电源(下载好小助手.VPN.个人证书) 手机.充电器 重要参考书籍 生活用品 衣服,夏天体恤为主,别忘了加件外套 被罩.床单和枕巾 牙刷牙膏肥皂之类的必带,中号浴巾一条 拖鞋要不要? ...
- android smali代码注入 实战一
有同学在通服里面干活,最近一直忙着4g基站搭建的干活,测试设备(android)测量移动网络数据,没有自动保存记录的功能,只能手动记录各种测试参数,不知道测试软件供应商是怎样想的,竟然不提供的这样的功 ...
- [译]在Javascript中制造二维数列
本文翻译youtube上的up主kudvenkat的javascript tutorial播放单 源地址在此: https://www.youtube.com/watch?v=PMsVM7rjupU& ...