Time Limit: 227MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu

Submit Status

Description

English Vietnamese

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.

Example

Input
5
1 1 2 1 3
3
1 5
2 4
3 5 Output
3
2
3

树状数组的方法:

/*
SPOJ DQUERY(hdu3333)线段树or树状数组离线
查询区间内不同数的个数
本来是学习主席树的,发现这方法不会也就写了下,感觉很机智
先将所有查询按区间右端从小到大排序,如果一个数已经出现过就先把以前位置上的删
掉然后在新的位置上插入,像这样在[l,r]中重复的就只计算了一次
hhh-2016-02-18 14:47:11
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <queue>
#include <vector>
using namespace std;
typedef long long ll;
typedef long double ld;
int tot;
map<int , int >mp;
const int maxn = 100010;
int n;
int a[maxn],ans[maxn*2];
int s[maxn]; struct node
{
int l,r,id;
} qu[maxn*2]; bool cmp(node a,node b)
{
return a.r < b.r;
} int lowbit(int x)
{
return x&(-x);
} void add(int x,int val)
{
for(int i = x ; i <= n; i+=lowbit(i))
s[i] += val;
} int query(int x)
{
int sum = 0;
for(int i = x; i > 0; i -= lowbit(i))
sum += s[i];
return sum;
} int main()
{
while(scanf("%d",&n) != EOF)
{
mp.clear();
memset(s,0,sizeof(s));
for(int i =1 ; i <= n; i++)
scanf("%d",&a[i]); int q;
scanf("%d",&q);
for(int i = 1; i <= q; i++)
{
scanf("%d%d",&qu[i].l,&qu[i].r);
qu[i].id = i;
}
sort(qu+1,qu+q+1,cmp);
int t = 1;
for(int i= 1;i <= q;i++)
{
for(;t <= qu[i].r;t++)
{
if(mp[a[t]] != 0) add(mp[a[t]],-1);
mp[a[t]] = t;
add(t,1);
}
ans[qu[i].id] = query(qu[i].r) - query(qu[i].l-1);
}
for(int i = 1;i <= q;i++)
{
printf("%d\n",ans[i]);
}
}
return 0;
} 主席树: //参考:关于主席树的读书笔记 将1-i用线段树处理,每个表示前i个数的情况。如果每棵线段都建完整的话肯定会mle,我们发现对于前缀[1,i]和前缀[1,i+1]的线段树,如果b[i+1]<=mid (b[i+1]表示a[i+1]离散后的标记) 那么线段树i和线段树i+1的左边是完全相同的,根本不需要在建,只需要用指针指一下就好 //忘了在(=@__@=)哪里看的了 换一种解释,如果我们要修改左子树,那么右子树上的与上一个线段树相比不会变化,只需要指一下就好 /*
主席树 SPOJ DQUERY
查询区间有多少个不同的数。类似于之前树状数组离线的思路,在插入之前先进行判断
如果已经有了,把以前的先删掉再进行插入
hhh-2016-02-18 15:37:48
*/ #include <functional>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <map>
#include <cmath>
using namespace std;
typedef long long ll;
typedef long double ld; using namespace std;
const int maxn = 100010;
int tot;
int n;
int a[maxn],t[maxn];
int T[maxn],lson[maxn*30],rson[maxn*30],c[maxn*30]; int build(int l,int r)
{
int root = tot++;
c[root] = 0;
if(l != r)
{
int mid = (l+r)>>1;
lson[root] = build(l,mid);
rson[root] = build(mid+1,r);
}
return root;
} //如果那里发生改变则兴建一个节点而非像平常修改那个节点的值
int update(int root,int pos,int val)
{
int newroot = tot++;
int tmp = newroot;
c[newroot] = c[root] + val;
int l = 1,r = n;
while(l < r)
{
int mid = (l+r)>>1;
if(pos <= mid)
{
lson[newroot] = tot++;
rson[newroot] = rson[root];
newroot = lson[newroot];
root = lson[root];
r = mid;
}
else
{
lson[newroot] = lson[root];
rson[newroot] = tot++;
newroot = rson[newroot];
root = rson[root];
l = mid+1;
}
c[newroot] = c[root] + val;
}
return tmp;
} int query(int root,int pos)
{
int l = 1, r = n;
int ans = 0;
while(pos > l)
{
int mid = (l+r)>>1;
if(pos <= mid)
{
ans += c[rson[root]];
r = mid;
root = lson[root];
}
else
{
l = mid+1;
root = rson[root];
}
}
return ans+c[root];
} int main()
{
while(scanf("%d",&n) !=EOF)
{
tot = 0;
map<int,int> mp;
for(int i = 1; i <= n; i++)
scanf("%d",&a[i]);
T[0] = build(1,n);
for(int i =1; i <= n; i++)
{
if(mp.find(a[i]) == mp.end())
T[i] = update(T[i-1],i,1);
else
{
int tt = update(T[i-1],mp[a[i]],-1);
T[i] = update(tt,i,1);
}
mp[a[i]] = i;
} int q;
scanf("%d",&q); while(q--)
{
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",query(T[r],l));
}
}
return 0;
}

  

SPOJ DQUERY树状数组离线or主席树的更多相关文章

  1. 洛谷 P1972"[SDOI2009]HH的项链"(离线+树状数组 or 在线+主席树)

    传送门 •题意 给你一个包含 n 个数的数组 $a$: 有 m 此操作,每次操作求区间 [l,r] 中不同数的个数: •题解(离线+树状数组) 以样例 $[1,2,3,4,3,5]$ 为例,求解区间 ...

  2. 【BZOJ1146】[CTSC2008]网络管理Network 树状数组+DFS序+主席树

    [BZOJ1146][CTSC2008]网络管理Network Description M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工 ...

  3. D-query SPOJ 树状数组+离线

    D-query SPOJ 树状数组+离线/莫队算法 题意 有一串正数,求一定区间中有多少个不同的数 解题思路--树状数组 说明一下,树状数组开始全部是零. 首先,我们存下所有需要查询的区间,然后根据右 ...

  4. 2016 Multi-University Training Contest 5 1012 World is Exploding 树状数组+离线化

    http://acm.hdu.edu.cn/showproblem.php?pid=5792 1012 World is Exploding 题意:选四个数,满足a<b and A[a]< ...

  5. Necklace HDU - 3874 (线段树/树状数组 + 离线处理)

    Necklace HDU - 3874  Mery has a beautiful necklace. The necklace is made up of N magic balls. Each b ...

  6. HDU 4325 离散化+树状数组 或者 不使用树状数组

    题意:给出一些花的开放时间段,然后询问某个时间点有几朵花正在开放. 由于ti<1e9,我们需要先将时间离散化,然后将时间点抽象为一个数组中的点,显然,我们需要进行区间更新和单点查询,可以考虑线段 ...

  7. BZOJ1878: [SDOI2009]HH的项链[树状数组+离线 | 主席树]

    题意: 询问区间不同种类颜色数 [2016-11-15] 离线好厉害 对于每一个区间询问,一个数只考虑一次,那么考虑他最后出现的一次 将询问按r排序 从1到n扫描,用树状数组维护一个位置应不应该考虑( ...

  8. BZOJ1878: [SDOI2009]HH的项链[树状数组 离线]

    1878: [SDOI2009]HH的项链 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 3486  Solved: 1738[Submit][Statu ...

  9. HDU3333 Turing Tree 树状数组+离线处理

    Turing Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

随机推荐

  1. 视频聊天插件:AnyChat使用攻略之iOS开发指南

    AnyChat使用攻略之iOS开发指南 这套攻略主要指导刚开始使用AnyChat SDK For iOS的同学,快速搭建SDK环境,和实现音视频开发流程. (需要工程案例文件可联系我们) 在iOS平台 ...

  2. 小草手把手教你 LabVIEW 串口仪器控制——VISA 串口配置

    建议大家按我发帖子的顺序来看,方便大家理解.请不要跳跃式的阅读.很多人现在看书,都跳跃式的看,选择性的看,导致有些细节的部分没有掌握到,然后又因为某个细节耽误很多时间.以上只是个人建议,高手可以略过本 ...

  3. HTTP协议以及HTTP2.0/1.1/1.0区别

    HTTP协议以及HTTP2.0/1.1/1.0区别 一.简介 摘自百度百科: 超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议.所 ...

  4. VMware虚拟机误删除vmdk文件后如何恢复?

    故障描述: Dell R710系列服务器(用于VMware虚拟主机),Dell MD 3200系列存储(用于存放虚拟机文件),VMware ESXi 5.5版本,因意外断电,导致某台虚拟机不能正常启动 ...

  5. JavaScript 实现二叉树

    JavaScript 实现二叉树: // JavaScript 实现二叉树 function BinaryTree () { var Node = function (key) { this.key ...

  6. 如何将portfolio产品图片上的悬停去掉?

    在Avada主题里,文章和portfolio的分类界面的图片,鼠标移入后都会出现这个东西 那么如何把它去掉,改为直接点击产品图片后进入产品详情页呢? 在theme option里搜索image rol ...

  7. Angular UI框架 Ng-alain @delon的脚手架的生成开发模板

    前言 首先感谢下 cipchk基于 Ng-Zorror 框架上制作的ng-alain . 之前很早就关注了 ng-alain,今天得空折腾了下. 折腾的时候发现官方文档有些坑,没有写清楚,所以我作为一 ...

  8. JavaScript 对图像进行(追加,插入,替换,删除)

    JavaScript 对图像进行(追加,插入,替换,删除) 本次所学内容: document.querySelector('.container') 这个是可以查找单个[id标签和class标签] d ...

  9. ArUco----一个微型现实增强库的介绍及视觉应用(二)

    ArUco----一个微型现实增强库的介绍及视觉应用(二) 一.第一个ArUco的视觉应用 首先介绍第一个视觉应用的Demo,这个应用场景比较简单,下面具体介绍: 1. 应用场景 主线程:通过摄像头检 ...

  10. ZOJ-1655 Transport Goods---dijkstra变形&&最长路

    题目链接: https://vjudge.net/problem/ZOJ-1655 题目大意: 有N-1个城市给首都(第N个城市)支援物资,有M条路,走每条路要耗费一定百分比的物资.问给定N-1个城市 ...