SPOJ - DQUERY (主席树求区间不同数的个数)
题目链接:https://vjudge.net/problem/SPOJ-DQUERY
题目大意:给定一个含有n个数的序列,有q个询问,每次询问区间[l,r]中不同数的个数。
解题思路:从左向右一个一个将该数字处在的位置添加到主席树中
如果该数字前面未出现过,则在此版本的线段树中的该条链加1,如果该数字已经出现过了,则在此版本线段树的上次出现位置减1,再在此版本线段树的该位置加1,这样就能保证区间不重复计算。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=;
struct node{
int l,r,sum;
}T[maxn*];
int n,q,a[maxn],cnt,root[maxn],pos[];
void update(int &now,int pre,int val,int l,int r,int pos){
T[++cnt]=T[pre],T[cnt].sum+=val,now=cnt;
if(l==r) return;
int mid=l+r>>;
if(pos<=mid) update(T[now].l,T[pre].l,val,l,mid,pos);
else update(T[now].r,T[pre].r,val,mid+,r,pos);
}
int query(int L,int R,int l,int r,int rt){
if(L<=l&&R>=r) return T[rt].sum;
int ans=,mid=l+r>>;
if(L<=mid) ans+=query(L,R,l,mid,T[rt].l);
if(R>mid) ans+=query(L,R,mid+,r,T[rt].r);
return ans;
}
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
for(int i=;i<=n;i++){
if(pos[a[i]]){
update(root[i],root[i-],-,,n,pos[a[i]]);
update(root[i],root[i],,,n,i);
}else update(root[i],root[i-],,,n,i);
pos[a[i]]=i;
}
scanf("%d",&q);
while(q--){
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",query(l,r,,n,root[r]));
}
return ;
}
SPOJ - DQUERY (主席树求区间不同数的个数)的更多相关文章
- 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) ...
- SPOJ - DQUERY 主席树求区间有多少个不同的数(模板)
D-query Time Limit: 227MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Submit Status ...
- SPOJ - 3267. D-query 主席树求区间个数
SPOJ - 3267 主席树的又一种写法. 从后端点开始添加主席树, 然后如果遇到出现过的元素先把那个点删除, 再更新树, 最后查询区间就好了. #include<bits/stdc++.h& ...
- hdu 5919--Sequence II(主席树--求区间不同数个数+区间第k大)
题目链接 Problem Description Mr. Frog has an integer sequence of length n, which can be denoted as a1,a2 ...
- SPOJ DQUERY (主席树求区间不同数个数)
题意:找n个数中无修改的区间不同数个数 题解:使用主席树在线做,我们不能使用权值线段树建主席树 我们需要这么想:从左向右添加一到主席树上,添加的是该数字处在的位置 但是如果该数字前面出现过,就在此版本 ...
- D-query SPOJ - DQUERY 主席树查询区间内不同数出现的次数
我们不以权值建立主席树,而是区间端点作为值建立线段树,一个个插入a[i],我们发现这个数之前是存在的,就需要在上个版本的主席树上减去原来的位置,并加上现在的位置,这样我们在i版本的主席树,维护1-r中 ...
- SPOJ 3267 求区间不同数的个数
题意:给定一个数列,每次查询一个区间不同数的个数. 做法:离线+BIT维护.将查询按右端点排序.从左到右扫,如果该数之前出现过,则将之前出现过的位置相应删除:当前位置则添加1.这样做就保证每次扫描到的 ...
- SPOJ 3267 D-query(离散化+主席树求区间内不同数的个数)
DQUERY - D-query #sorting #tree English Vietnamese Given a sequence of n numbers a1, a2, ..., an and ...
- 主席树——求区间[l,r]不同数字个数的模板(向左密集 D-query)
主席树的另一种用途,,(还有一种是求区间第k大,区间<=k的个数) 事实上:每个版本的主席树维护了每个值最后出现的位置 这种主席树不是以权值线段树为基础,而是以普通的线段树为下标的 /* 无修改 ...
随机推荐
- TCP报文段首部格式详解
TCP首部格式 格式字段详解 源端口.目标端口: 计算机上的进程要和其他进程通信是要通过计算机端口的,而一个计算机端口某个时刻只能被一个进程占用,所以通过指定源端口和目标端口,就可以知道是哪两 ...
- The import org.apache.hadoop.mapreduce cannot be resolved
ubuntu@VM---ubuntu:~$ sudo apt--src.tar.gz Reading package lists... Done Building dependency tree Re ...
- (转)SQLite部署-无法加载 DLL“SQLite.Interop.dll”: 找不到指定的模块
本文转载自:http://www.cnblogs.com/muzhiye/p/4284070.html 近期刚使用SQLite,主要引用的是System.Data.SQLite.dll这个dll,在部 ...
- ThreadPoolExecutor 源码分析
ThreadPoolExecutor 线程池核心实现类 线程池的生命周期 RUNNING: 接受新任务,同时处理工作队列中的任务 SHUTDOWN: 不接受新任务,但是能处理工作队列中的任务 STOP ...
- 用Vue来实现音乐播放器(八):自动轮播图啊
slider.vue组件的模板部分 <template> <div class="slider" ref="slider"> <d ...
- 《计算机程式设计》Week2 课堂笔记
本笔记记录自 Coursera课程 <计算机程式设计> 台湾大学 刘邦锋老师 Week2 Control Structure 2-1 If-then-else if then 判断 if ...
- C# datatable 导出到Excel
datatable导出到Excel /// <summary> /// 将DataTable导出为Excel文件(.xls) /// </summary> /// <pa ...
- 【公众号系列】SAP 主要模块及简介
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[公众号系列]SAP 主要模块及简介 前言部 ...
- Apache httpclient拦截器对请求进行签名
Apahce httpclient 提供HttpRequestInterceptor和HttpResponseInterceptor两种拦截器分别处理请求和响应数据,下面讲一下如何对http请求进行拦 ...
- sql exist 和not exist(转载)
exists : 强调的是是否返回结果集,不要求知道返回什么, 比如: select name from student where sex = 'm' and mark exists(select ...