主席树的另一种用途,,(还有一种是求区间第k大,区间<=k的个数)

事实上:每个版本的主席树维护了每个值最后出现的位置

这种主席树不是以权值线段树为基础,而是以普通的线段树为下标的

/*
无修改,求区间[l,r]有多少个不同的数
主席树的另外一种姿势:
不像求区间第k大,区间<=k的数有几个之类的可持久化权值线段树,每个结点维护的是当前版本x的出现次数
本题的主席树每个结点维护当前版本下位置i的值的出现情况
更新:以数组a为基础建立线段树,然后从左往右扫描a
当扫到ai时,如果ai是第一次出现,那么直接在新的线段树上在i位置 +1
如果值ai在前面位置p出现过,那么在新的线段树上将 p位置 -1,在i位置 +1
询问:[l,r]
首先明确第r棵线段树的rt[1]是[1,r]区间上的不同的数的个数
现在要求[l,r]上不同的数的个数,那就要把第r棵线段数[l,r]区间的和求出来
所以只要询问第r棵线段树区间[l,n]的和即可 可以发现本题并没有用到类似前缀和的思想,因为只要保存各个版本的主席树即可
*/
#include<bits/stdc++.h>
using namespace std;
#define maxn 1000005
struct Node{int lc,rc,sum;}t[*];
int n,a[maxn],rt[maxn],size,q,pre[maxn],last[maxn];
int build(int l,int r){
int now=++size;
t[now].lc=t[now].rc=t[now].sum=;
if(l==r)return now;
int mid=l+r>>;
t[now].lc=build(l,mid);
t[now].rc=build(mid+,r);
return now;
}
int update(int last,int pos,int val,int l,int r){//位置pos+val
int now=++size;
t[now]=t[last];t[now].sum+=val;
if(l==r)return now;
int mid=l+r>>;
if(pos<=mid)t[now].lc=update(t[last].lc,pos,val,l,mid);
else t[now].rc=update(t[last].rc,pos,val,mid+,r);
return now;
}
int query(int rt,int L,int R,int l,int r){//查询[L,R]的区间和
if(L<=l && R>=r) return t[rt].sum;
int mid=l+r>>,res=;
if(L<=mid)res+=query(t[rt].lc,L,R,l,mid);
if(R>mid)res+=query(t[rt].rc,L,R,mid+,r);
return res;
}
int main(){
cin>>n;
for(int i=;i<=n;i++){
scanf("%d",&a[i]) ;
pre[i]=last[a[i]];//上一次出现位置
last[a[i]]=i;
}
rt[]=build(,n);
for(int i=;i<=n;i++){
if(pre[i]==)rt[i]=update(rt[i-],i,,,n);//这个位置+1
else{
int tmp=update(rt[i-],pre[i],-,,n);
rt[i]=update(tmp,i,,,n);
}
}
cin>>q;
while(q--){
int l,r;
scanf("%d%d",&l,&r);
//cout<<t[rt[r]].sum<<'\n';
cout<<query(rt[r],l,n,,n)<<'\n';
}
}

主席树——求区间[l,r]不同数字个数的模板(向左密集 D-query)的更多相关文章

  1. SPOJ 3267 D-query(离散化+主席树求区间内不同数的个数)

    DQUERY - D-query #sorting #tree English Vietnamese Given a sequence of n numbers a1, a2, ..., an and ...

  2. SPOJ - DQUERY 主席树求区间有多少个不同的数(模板)

    D-query Time Limit: 227MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Submit Status ...

  3. 主席树——求区间第k个不同的数字(向右密集hdu5919)

    和向左密集比起来向右密集只需要进行小小的额修改,就是更新的时候从右往左更新.. 自己写的被卡死时间.不知道怎么回事,和网上博客的没啥区别.. /* 给定一个n个数的序列a 每次询问区间[l,r],求出 ...

  4. SPOJ DQUERY (主席树求区间不同数个数)

    题意:找n个数中无修改的区间不同数个数 题解:使用主席树在线做,我们不能使用权值线段树建主席树 我们需要这么想:从左向右添加一到主席树上,添加的是该数字处在的位置 但是如果该数字前面出现过,就在此版本 ...

  5. SPOJ - DQUERY (主席树求区间不同数的个数)

    题目链接:https://vjudge.net/problem/SPOJ-DQUERY 题目大意:给定一个含有n个数的序列,有q个询问,每次询问区间[l,r]中不同数的个数. 解题思路:从左向右一个一 ...

  6. HDU 4417 Super Mario(主席树求区间内的区间查询+离散化)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  7. hdu 5919--Sequence II(主席树--求区间不同数个数+区间第k大)

    题目链接 Problem Description Mr. Frog has an integer sequence of length n, which can be denoted as a1,a2 ...

  8. hdu4417 主席树求区间小于等于K

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4417   Problem Description Mario is world-famous plum ...

  9. SPOJ:D-query(非常规主席树求区间不同数的个数)

    Given a sequence of n numbers a1, a2, ..., an and a number of d-queries. A d-query is a pair (i, j) ...

随机推荐

  1. sprigboot recontroller 是responsebody与controller结合 这样 就使每个方法默认返回json

    sprigboot   recontroller 是responsebody与controller结合 这样 就使每个方法默认返回json

  2. C博客作业01--分支、顺序结构

    1.本章学习总结 1.1 思维导图 1.2 本章学习体会及代码量学习体会 1.2.1 学习体会 在暑假已经有初步接触c语言,所以在学习c语言的开始会比较轻松,但仍然解题时候步骤太过于繁琐,简单的题目复 ...

  3. CF 1119C Ramesses and Corner Inversion

    https://codeforces.com/problemset/problem/1119/C 题目 给两个矩阵,只能选宽和高大于等于2的子矩阵左上.左下.右上.右下四点翻转(1->0,0-& ...

  4. mysql生成20万条数据(连表插入)

    创建一个存储过程 DELIMITER $$ -- 设置定界符为$$,与';'意思相同,防止相同符号产生冲突 USE `yunkc_base1`$$ -- 使用数据库 DROP PROCEDURE IF ...

  5. spring-webmvc-DispatcherServlet

    Spring Web MVC is the original web framework built on the Servlet API and has been included in the S ...

  6. 【php】php7新特性及其优化原理

    php7.x版本系列相比之前的php的版本提交性能提高了不少,这里面其中的一些主要改变是性能提高的关键,主要有以下内容. 1.zval使用栈内存   在zend引擎和扩展中,经常要创建php变量,其底 ...

  7. Spring Boot整合Elasticsearch

    Spring Boot整合Elasticsearch   Elasticsearch是一个全文搜索引擎,专门用于处理大型数据集.根据描述,自然而然使用它来存储和搜索应用程序日志.与Logstash和K ...

  8. flink部署操作-flink standalone集群安装部署

    flink集群安装部署 standalone集群模式 必须依赖 必须的软件 JAVA_HOME配置 flink安装 配置flink 启动flink 添加Jobmanager/taskmanager 实 ...

  9. 微信小程序之:wepy(二)

    一大堆实例:人家的博客园 代码规范: 1.尽量使用驼峰命名,避免使用$开头,框架内建属性都已$开头,可以使用this直接调用. 2.入口文件.页面.组件后缀都为.wpy. 3.使用ES6语法开发. 4 ...

  10. H5_0005:JS判断域名和时间有效期的方法

    (function () { var n = { c: function (t, e) { //console.log("c"); //把i(15)的d数组转换成字串 for (v ...