主席树的另一种用途,,(还有一种是求区间第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. 【DeepLearning】深入理解dropout正则化

    本文为转载,作者:Microstrong0305 来源:CSDN 原文:https://blog.csdn.net/program_developer/article/details/80737724 ...

  2. 【C++】GSL(GNU Scientific Library) 的安装及在 Visual Studio 2017 中的使用

    GSL 是 GNU 开发并维护的科学计算的库,其中包括: 复数 多项式的根 特殊函数 向量和矩阵 排列 排序 BLAS支持 线性代数 Eigensystems 快速傅立叶变换 正交 随机数 准随机序列 ...

  3. 基于H5的混合开发介绍(一)WebView

    转自: https://www.cnblogs.com/sanchang/p/9261461.html 一 WebView到底是什么    1 WebView是一种控件,它基于webkit引擎,因此具 ...

  4. 第三周博客作业<西北师范大学|李晓婷>

    1.助教博客链接:https://www.cnblogs.com/lxt-/MyComments.html 2.学生作业打分要求:   https://www.cnblogs.com/nwnu-dai ...

  5. ubuntu上安装multi-mechanize步骤

    第一步:先安装pip pip 是 Python 包管理工具,该工具提供了对Python 包的查找.下载.安装.卸载的功能. 目前如果你在 python.org 下载最新版本的安装包,则是已经自带了该工 ...

  6. dataTable 实战总结

    后台项目中经常会用到 dataTable 进行表格的智能绘制:总结一下项目中经常用到的 dataTable 设置 1.dataTable 属性设置: autoWidth: true, // 是否自动计 ...

  7. windows 下启动运行 jar 包程序

    windows 下 运行 jar 包 java -jar XXX.jar java -server -Xms1024m -Xmx20480m -jar $JAR_NAME.jar windows 后台 ...

  8. ztree树应用

    <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ZtreeListVi ...

  9. JAVA的运算符和条件结构

    一.JAVA的运算符. 1.赋值运算符 赋值就是把一个变量的值赋给另一个变量. 语法: 变量名=表达式     例如  n = m + 5 2.算术运算符      算术运算符是数学中常用的加.减.乘 ...

  10. Apple Tree POJ - 2486 (树形dp)

    题目链接: D - 树形dp  POJ - 2486 题目大意:一颗树,n个点(1-n),n-1条边,每个点上有一个权值,求从1出发,走V步,最多能遍历到的权值 学习网址:https://blog.c ...