题目

Source

http://www.spoj.com/problems/DQUERY/en/

Description

Given a sequence of n numbers a1, a2, ..., an and a number of d-queries. A d-query is a pair (i, j) (1 ≤ i ≤ j ≤ n). For each d-query (i, j), you have to return the number of distinct elements in the subsequence ai, ai+1, ..., aj.

Input

Line 1: n (1 ≤ n ≤ 30000).
Line 2: n numbers a1, a2, ..., an (1 ≤ ai ≤ 106).
Line 3: q (1 ≤ q ≤ 200000), the number of d-queries.
In the next q lines, each line contains 2 numbers i, j representing a d-query (1 ≤ i ≤ j ≤ n).

Output

For each d-query (i, j), print the number of distinct elements in the subsequence ai, ai+1, ..., aj in a single line.

Sample Input

5
1 1 2 1 3
3
1 5
2 4
3 5

Sample Output

3
2
3

分析

题目说给一个序列,多次询问一个区间内不同数的个数。

离线做法很经典吧,HDU3333
主席树做法。。其实很容易往建权值线段树那边想,不过好像行不通。。

其实做法也和离线是一样的,线段树维护的是各个位置是否要存在数,记录各个数出现最右边的位置,删除之前的位置、更新当前位置,相当于把各个数字一直往右靠。

于是这样就从左往右保存了多个版本的线段树信息,查询时就拿出右端点对应版本的线段树进行区间查询。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 33333 int x,y,root[MAXN],tree[MAXN*20],lch[MAXN*20],rch[MAXN*20],N; void update(int i,int j,int a,int &b){
b=++N;
if(i==j){
tree[b]=tree[a]+y;
return;
}
int mid=i+j>>1;
lch[b]=lch[a]; rch[b]=rch[a];
if(x<=mid) update(i,mid,lch[a],lch[b]);
else update(mid+1,j,rch[a],rch[b]);
tree[b]=tree[lch[b]]+tree[rch[b]];
}
int query(int i,int j,int a){
if(x<=i && j<=y){
return tree[a];
}
int mid=i+j>>1,ret=0;
if(x<=mid) ret+=query(i,mid,lch[a]);
if(y>mid) ret+=query(mid+1,j,rch[a]);
return ret;
} int a[MAXN],last[1111111];
int main(){
int n,q;
scanf("%d",&n);
for(int i=1; i<=n; ++i){
scanf("%d",&a[i]);
} for(int i=1; i<=n; ++i){
if(last[a[i]]){
int tmp; x=last[a[i]]; y=-1;
update(1,n,root[i-1],tmp);
x=i; y=1;
update(1,n,tmp,root[i]);
}else{
x=i; y=1;
update(1,n,root[i-1],root[i]);
}
last[a[i]]=i;
} scanf("%d",&q);
while(q--){
scanf("%d%d",&x,&y);
printf("%d\n",query(1,n,root[y]));
}
return 0;
}

SPOJ DQUERY 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 (在线主席树/ 离线树状数组)

    版权声明:本文为博主原创文章,未经博主允许不得转载. SPOJ DQUERY 题意: 给出一串数,询问[L,R]区间中有多少个不同的数 . 解法: 关键是查询到某个右端点时,使其左边出现过的数都记录在 ...

  3. 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) ...

  4. SPOJ - COT 路径构造主席树

    题意:给出一个带权树,多次询问路径\((u,v)\)的第k小权值 这是主席树往区间扩展到树上的套路题 由于是按路径查询,我们无法使用dfs序,但可利用主席树对父亲扩展的方法构造出链 因此要用dfs构造 ...

  5. EC Round 33 F. Subtree Minimum Query 主席树/线段树合并

    这题非常好!!! 主席树版本 很简单的题目,给一个按照指定节点的树,树上有点权,你需要回答给定节点的子树中,和其距离不超过k的节点中,权值最小的. 肯定首先一想,按照dfs序列建树,然后按照深度为下标 ...

  6. CF893F Subtree Minimum Query 主席树

    如果是求和就很好做了... 不是求和也无伤大雅.... 一维太难限制条件了,考虑二维限制 一维$dfs$序,一维$dep$序 询问$(x, k)$对应着在$dfs$上查$[dfn[x], dfn[x] ...

  7. SPOJ DQUERY 离线树状数组+离散化

    LINK 题意:给出$(n <= 30000)$个数,$q <= 2e5$个查询,每个查询要求给出$[l,r]$内不同元素的个数 思路:这题可用主席树查询历史版本的方法做,感觉这个比较容易 ...

  8. 2018.08.04 spoj TTM to the moon(主席树)

    spoj传送门 vjudge传送门 主席树板子题. 支持历史版本的区间和,区间和,区间修改和时光倒流. 其中新奇一点的也只有区间修改了,这个东西直接标记永久化就行了. 如果想下传标记的话也行,需要在p ...

  9. [主席树]SPOJ DQUERY

    题目链接 题意:n个数 m个查询 查询的是[l, r]区间内不相同的数的个数 没有修改,因此静态的主席树就好了 将重复的元素建树即可 query的时候加起来,用区间长度(r-l+1)去减就是答案 (q ...

随机推荐

  1. 【转】使用SQL Tuning Advisor STA优化SQL

    SQL优化器(SQL Tuning Advisor STA)是Oracle10g中推出的帮助DBA优化工具,它的特点是简单.智能,DBA值需要调用函数就可以给出一个性能很差的语句的优化结果.下面介绍一 ...

  2. Easyui 设置datagrid 进入编辑状态,保存结束编辑

    在datagrid中如何实现让一行进入编辑状态,修改数据后,保存信息呢? //点击列表变成文本框,进入可编辑状态 $(function () { var doc = $(document), tabl ...

  3. php使用openssl进行Rsa长数据加密(117)解密(128) 和 DES 加密解密

    PHP使用openssl进行Rsa加密,如果要加密的明文太长则会出错,解决方法:加密的时候117个字符加密一次,然后把所有的密文拼接成一个密文:解密的时候需要128个字符解密一下,然后拼接成数据. 加 ...

  4. google觉得好用的插件(不断更新)

    1.Octotree 访问github可以显示工程结构. 2.vysor 免费版可以让手机在电脑演示,其中付费版还可以电脑操作手机.

  5. JS学习:第二周——NO.2正则

    1.[正则] 就是用来操作(匹配和捕获)的一系列规则: 匹配:校验字符串是否符合我们的规则:返回值--布尔值           匹配这里用的是正则的方法:test(),reg.text( ); 捕获 ...

  6. angularjs 中的setTimeout(),setInterval() / $interval 和 $timeout

    $interval window.setInterval的Angular包装形式.Fn是每次延迟时间后被执行的函数. 间隔函数的返回值是一个承诺.这个承诺将在每个间隔刻度被通知,并且到达规定迭代次数后 ...

  7. 在VisualStudio 编辑器文本替换中使用正则表达式

    替换时使用正则表达式,其优点在于可以通过正则分组捕获,并在替换字符串中使用. 在VS2012之前的版本中,捕获内容用{}包含,引用时,使用 \1 形式: 在VS2012及以后版本中,捕获内容符合正则表 ...

  8. C#网络编程数据传输中封装数据帧头的方法

    在C/S端编程的时候,经常要在C端和S端之间传数据时自定义一下报文的帧头,如果是在C/C++,封装帧头是一件很简单的事情,直接把unsigned char *强转为struct就行,但是在C#中,并没 ...

  9. item2快捷键

    整理使用 iTerm 2 过程中得常用快捷键,Mac 原来自带的终端工具 Terminal 不好用是出了名的,虽然最近几个版本苹果稍微做了些优化,功能上,可用性方面增强不少,无奈有个更好用的 Iter ...

  10. 循环获取DataTable

    DataTable ddtt = tq.Table("); string strName = ""; //DataTable ddtt = dataSet.Tables[ ...