题目

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
主席树做法。。其实很容易往建权值线段树那边想,不过好像行不通。。

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

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

代码

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. using namespace std;
  5. #define MAXN 33333
  6.  
  7. int x,y,root[MAXN],tree[MAXN*20],lch[MAXN*20],rch[MAXN*20],N;
  8.  
  9. void update(int i,int j,int a,int &b){
  10. b=++N;
  11. if(i==j){
  12. tree[b]=tree[a]+y;
  13. return;
  14. }
  15. int mid=i+j>>1;
  16. lch[b]=lch[a]; rch[b]=rch[a];
  17. if(x<=mid) update(i,mid,lch[a],lch[b]);
  18. else update(mid+1,j,rch[a],rch[b]);
  19. tree[b]=tree[lch[b]]+tree[rch[b]];
  20. }
  21. int query(int i,int j,int a){
  22. if(x<=i && j<=y){
  23. return tree[a];
  24. }
  25. int mid=i+j>>1,ret=0;
  26. if(x<=mid) ret+=query(i,mid,lch[a]);
  27. if(y>mid) ret+=query(mid+1,j,rch[a]);
  28. return ret;
  29. }
  30.  
  31. int a[MAXN],last[1111111];
  32. int main(){
  33. int n,q;
  34. scanf("%d",&n);
  35. for(int i=1; i<=n; ++i){
  36. scanf("%d",&a[i]);
  37. }
  38.  
  39. for(int i=1; i<=n; ++i){
  40. if(last[a[i]]){
  41. int tmp; x=last[a[i]]; y=-1;
  42. update(1,n,root[i-1],tmp);
  43. x=i; y=1;
  44. update(1,n,tmp,root[i]);
  45. }else{
  46. x=i; y=1;
  47. update(1,n,root[i-1],root[i]);
  48. }
  49. last[a[i]]=i;
  50. }
  51.  
  52. scanf("%d",&q);
  53. while(q--){
  54. scanf("%d%d",&x,&y);
  55. printf("%d\n",query(1,n,root[y]));
  56. }
  57. return 0;
  58. }

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. laravel强大功能路由初探(二)

    目标当然是先输出helloworld 配置hosts文件和apache下的httpd-vhosts.conf, hosts:127.0.0.1  www.blog.com httpd-vhosts.c ...

  2. 错误:java.util.Map is an interface, and JAXB can't handle interfaces.

    问题: 在整合spring+cxf时报错java.util.Map is an interface, and JAXB can't handle interfaces. 解决方法: 将服务端的serv ...

  3. mac 下设置jdk 路径,设置hadoop 路径

    1. touch ~/.bash_profile  创建一个文件 2.vim ~/.bash_profile JAVA_HOME=/Library/Java/JavaVirtualMachines/j ...

  4. window.onload =writeMessage(); 与window.onload =writeMessage;的区别

    window.onload =writeMessage(); window.onload =writeMessage; 异:第一种是window加载时执行writeMesage方法,第二种是把writ ...

  5. centos 7 配置网络

    文档: https://wiki.centos.org/FAQ/CentOS7

  6. nginx windows负载均衡入门

    前言 做了几年开发,都是只管码代码,没有参与过项目的部署,为了知识体系更加完整,于是开始学习一下负载均衡.查了一下资料,觉得用nginx +iis 比较简单,于是小试牛刀. 步骤 准备工作 下载ngi ...

  7. 前端模拟 图片上传---->>通过选取的图片获取其路径<<------

    <head> <meta charset="UTF-8"> <title>Title</title> <style> d ...

  8. plist文件里边如果最外层是字典的话,读出来是无序的。

    如题. 要想使字典有序的话,可以用数组来存放字典,然后读

  9. heightcharts

    title:标题 subtitle:子标题 data:eval(dataList)//数据格式转换

  10. CentOS7 NTP 安装配置

    NTP 网络时间协议用来同步网络上不同主机的系统时间.你管理的所有主机都可以和一个指定的被称为 NTP 服务器的时间服务器同步它们的时间.而另一方面,一个 NTP 服务器会将它的时间和任意公共 NTP ...