SPOJ - DQUERY 主席树
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=32356
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.
题意:给出很多询问,求出每次询问数列中连续区间的不同的数的个数。
算法分析:算法思想是主席树,这个算法真是神奇得没话说,必须得崇拜呀。由于刚接触这个算法思想,所以主席树是参照kuangbin大牛的模板来写的。
引用主席树的发明人说过的两句话:
这个东西是当初我弱不会划分树的时候写出来替代的一个玩意..被一小撮别有用心的人取了很奇怪的名字> < 。
想法是对原序列的每一个前缀[1..i]建立出一颗线段树维护值域上每个数的出现次数,然后发现这样的树是可以减的,然后就没有然后了 。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#define inf 0x7fffffff
using namespace std;
const int maxn=+;
const int M = maxn*+; int n,q,tot;
int an[maxn];
int T[maxn],lson[M],rson[M],c[M];
int build(int l,int r)
{
int root=tot++;
c[root]=;
if (l!=r)
{
int mid=(l+r)>>;
lson[root]=build(l,mid);
rson[root]=build(mid+,r);
}
return root;
}
int update(int root,int pos,int val)
{
int newroot=tot++,tmp=newroot;
c[newroot]=c[root]+val;
int l=,r=n;
while (l<r)
{
int mid=(l+r)>>;
if (pos<=mid)
{
lson[newroot]=tot++ ;rson[newroot]=rson[root];
newroot=lson[newroot] ;root=lson[root];
r=mid;
}
else
{
rson[newroot]=tot++ ;lson[newroot]=lson[root];
newroot=rson[newroot] ;root=rson[root];
l=mid+;
}
c[newroot]=c[root]+val;
}
return tmp;
}
int query(int root,int pos)
{
int ret=;
int l=,r=n;
while (pos<r)
{
int mid=(l+r)>>;
if (pos<=mid) {r=mid ;root=lson[root] ;}
else {ret += c[lson[root] ] ;root=rson[root] ;l=mid+ ;}
}
return ret+c[root];
}
int main()
{
while (scanf("%d",&n)!=EOF)
{
tot=;
for (int i= ;i<=n ;i++) scanf("%d",&an[i]);
T[n+]=build(,n);
map<int,int> mp;
mp.clear();
for (int i=n ;i>= ;i--)
{
if (mp.find(an[i])==mp.end())
T[i]=update(T[i+],i,);
else
{
int tmp=update(T[i+],mp[an[i] ],-);
T[i]=update(tmp,i,);
}
mp[an[i] ]=i;
}
scanf("%d",&q);
while (q--)
{
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",query(T[l],r));
}
}
return ;
}
SPOJ - DQUERY 主席树的更多相关文章
- SPOJ - DQUERY 主席树求区间有多少个不同的数(模板)
D-query Time Limit: 227MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Submit Status ...
- D-query SPOJ - DQUERY 主席树查询区间内不同数出现的次数
我们不以权值建立主席树,而是区间端点作为值建立线段树,一个个插入a[i],我们发现这个数之前是存在的,就需要在上个版本的主席树上减去原来的位置,并加上现在的位置,这样我们在i版本的主席树,维护1-r中 ...
- SPOJ - 3267. D-query 主席树求区间个数
SPOJ - 3267 主席树的又一种写法. 从后端点开始添加主席树, 然后如果遇到出现过的元素先把那个点删除, 再更新树, 最后查询区间就好了. #include<bits/stdc++.h& ...
- Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式)
Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式) 题外话,这是我第40篇随笔,纪念一下.<( ̄︶ ̄)↗[GO!] 题意 是说有棵树,每个节点上 ...
- SPOJ DQUERY 离线树状数组+离散化
LINK 题意:给出$(n <= 30000)$个数,$q <= 2e5$个查询,每个查询要求给出$[l,r]$内不同元素的个数 思路:这题可用主席树查询历史版本的方法做,感觉这个比较容易 ...
- SPOJ - TTM 主席树
给你一个系列\(a[1...n]\),要求可以区间求和,区间更新,也可以回溯过去 经典的主席树板子题,很久以前做的题了,代码太丑回炉重写 PS.题目标题To The Moon也是我最喜欢的游戏之一 这 ...
- $SP$3267 $DQUERY - D-query$ 主席树
正解:主席树 解题报告: 传送门! 一直在做$dp$题好久没做做别的了,,,所以来做点儿别的练练手,,,不然以前学的全忘了要/$kk$ 然后这题好像可以莫队/主席树/线段树/树状数组? 我就先只港下主 ...
- SPOJ - DQUERY D-query 主席树
题意; 给一个数列$\{ a_i\}$ 一些询问$(l_i,r_i)$ 问你$[l,r]$有多少个不同元素 题解: 其实本质思路和离线化处理询问的线段树/树状数组写法差不多,对区间$[x,r]$来说, ...
- SPOJ DQUERY D-query(主席树)
题目 Source http://www.spoj.com/problems/DQUERY/en/ Description Given a sequence of n numbers a1, a2, ...
随机推荐
- winform 自定义控件以及委托事件的使用
源代码:http://files.cnblogs.com/files/qtiger/%E8%AE%A1%E7%AE%97%E5%99%A8%E5%AE%89%E8%A3%85%E5%8C%85%E4% ...
- 如何调节datagridview中字体
设置ColumnHeaderDefaultCellStyle的Font属性 或者 编程 datagridview.Columns[index].DefaultCellStyle.Font.Size=“ ...
- Winform登录、控制软件只运行一次、回车登录
Winform登录对很多程序猿来说都有些困惑,登录进入主窗体后要销毁登录窗体,而不是隐藏哦,怎么实现呢? 先贴一段Program.cs的代码 static void Main() { Mutex mu ...
- Silverlight IIs发布问题
1.在IIS上部署系统没有问题,在vs中链接oracle中出错(数据连接不成功,请检查该数据库是否已启动尝试加载oracle客户端时引发BadImageFormatException.如果在安装32位 ...
- Android中内容观察者的使用---- ContentObserver类详解
详解:http://blog.csdn.net/qinjuning/article/details/7047607
- Java命名:
如果没有public类,就和遵循文件名命名规则: 1.一个.java文件只能有1个public class(暗示可以没有) 2.如果有public class,那么文件名必须与修饰符为public的类 ...
- 在一般处理程序中,把Form Post过来的表单集合转换成对象 ,仿 MVC post,反射原理
using System; using System.Collections.Generic; using System.Collections.Specialized; using System.L ...
- prettyprint
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- open/fopen read/fread write/fwrite区别
fopen /open区别 UNIX环境下的C 对二进制流文件的读写有两套班子:1) fopen,fread,fwrite ; 2) open, read, write这里简单的介绍一下他们的区别.1 ...
- 宝马测试(C++实现)
测试目的:对编辑器放大,缩小性能测试. 测试资源:一匹宝马. 测试结果:良好. 实现方法:通过调用本地保存的宝马文件,逐字逐行的显示在编辑器中,并放大,缩小.对不同的符号进 ...