主席树的另一种用途,,(还有一种是求区间第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. NC 命令引用了一个高手的文章做收藏

    什么是nc nc是netcat的简写,有着网络界的瑞士军刀美誉.因为它短小精悍.功能实用,被设计为一个简单.可靠的网络工具 nc的作用 (1)实现任意TCP/UDP端口的侦听,nc可以作为server ...

  2. 抽奖大转盘 js代码

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. 最简单的JAVA解析XML字符串方法

    引入 dom4j 包<dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifa ...

  4. 洛谷P2179 骑行川藏

    什么毒瘤... 解:n = 1的,发现就是一个二次函数,解出来一个v的取值范围,选最大的即可. n = 2的,猜测可以三分.于是先二分给第一段路多少能量,然后用上面的方法求第二段路的最短时间.注意剩余 ...

  5. 如何优雅地用Redis实现分布式锁?

    转: 如何优雅地用Redis实现分布式锁?   BaiduSpring 01-2500:01 什么是分布式锁 在学习Java多线程编程的时候,锁是一个很重要也很基础的概念,锁可以看成是多线程情况下访问 ...

  6. thinkphp5 去除缓存

    array_map('unlink', glob(TEMP_PATH . '/*.php')); rmdir(TEMP_PATH);

  7. 【优秀的iPhone/iPad数据恢复工具】Omni Recover for Mac 2.5

    [简介] 今天和大家分享最新的 Omni Recover for Mac 2.5 版本,这是一款Mac上优秀的iPhone/iPad设备数据恢复工具,支持恢复误删除的短信.照片.视频.文档.通话记录等 ...

  8. python放弃篇(Django/爬虫)

    第一篇:Django系列 第二篇:爬虫系列 待续……

  9. JN_0007:微信昵称设置小数字

    请复制下面背景色里面的数字符号 上标: ℡º ¹ ² ³ ⁴ ⁵ ⁶ ⁷ ⁸ ⁹ ⁺ ⁻ ⁼ ⁽ ⁾ ⁿ ′ ½ 下标: ℡.₀ ₁ ₂ ₃ ₄ ₅ ₆ ₇ ₈ ₉ ₊ ₋ ₌ ₍ ₎ 复制上面那串数 ...

  10. 实时通讯系列目录篇之SignalR详解

    一. 简单说几句 最早使用SignalR的时候大约是两年前了,记得当时是一个OA中消息的实时提醒,轮询的方式有点耗资源,WebSocket写起来又比较麻烦,最终选择了SignalR,当时是什么版本已经 ...