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, ...
随机推荐
- winfrom之动态控件生成以及保存动态空间的数据
前些天要完成一个winform程序,里面涉及到动态控件的添加以及保存动态空间中数据的保存,效果如下 初始化时: 点击添加阶梯价后:(点击一下,动态添加一行) 那么接下来,我们就具体的讲下代码实现: 首 ...
- 在Windows下Mysql如何重置root用户密码
原文链接:http://www.feeldesignstudio.com/2013/05/windows-mysql-root-password-reset 网上的很多在Windows下重置root用 ...
- 【漫画解读】HDFS存储原理(转载)
以简洁易懂的漫画形式讲解HDFS存储机制与运行原理. 一.角色出演 如上图所示,HDFS存储相关角色与功能如下: Client:客户端,系统使用者,调用HDFS API操作文件;与NN交互获取文件元数 ...
- Php output buffering缓存及程序缓存
在php中有时为了控制程序的输出显示顺序,提供了output buffering缓存(php自身缓存机制). 若Ob缓存开启,需要输出的就先存在ob缓存里,再到程序缓存里.若没有开启,则直接进入 ...
- U6会计科目导入致对账不平
一个客户,用的是U6版本,想将己使用的账套的科目导入新建的账套中,本想用用友本身自带的总账工具导入,发现导不了.没办法,只能打开数据库,手工导入. 月末结账时,发现对账不平.问题是余额表与明细不平,大 ...
- 正确打印含unicode字符的dict
python中,dict 对象转换为类似为 \UXXXX 的格式:这种格式英文称为 code point,完全看不懂:当然,也可以通过这个网站来转换 http://rishida.net/tools/ ...
- stm32f103 SPI单线TX发数据来驱动LCD
有一黑白LCD,有CS/SI/SCK三线,时序满足SPI时序,但STM32的SPI有四线NSS/MOSI/SCK/MISO,这里MISO没有用到.因此可以使用SPI的单线发送模式进行驱动LCD. 关键 ...
- Android 解决图片大量下载:软引用必须懂4点
1.对象的强.软.弱和虚引用为了能更加灵活控制对象的生命周期,需要知道对象引用的4中级别,由高到低依次为 :强引用.软引用.弱引用和虚引用 备注: 这四种的区别: ⑴强引用(StrongReferen ...
- mousewheel滚轮事件
原生的滚轮事件:火狐与其他浏览器使用了不同的事件 /* * 滚轮事件只有firefox比较特殊,使用DOMMouseScroll; 其他浏览器使用mousewheel; * */ // firefox ...
- Go循环引用问题
在Go中,不支持循环引用,即package a引用了packageb以后,package b就不能引用package a了. 最简单的场景: package a中定义context.go用来保存上下文 ...