SPOJ DQUERY D-query (在线主席树/ 离线树状数组)
版权声明:本文为博主原创文章,未经博主允许不得转载。
题意:
给出一串数,询问[L,R]区间中有多少个不同的数 。
解法:
关键是查询到某个右端点时,使其左边出现过的数都记录在它们出现的最右位置置1,其他位置置0,然后直接统计[L,R]的区间和就行了。
在线和离线都可以做 。
话不多说,上代码 。
在线主席树
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <map>
#define ll long long using namespace std; const int N=+;
const int M=+; int Ls[N*],Rs[N*],sum[N*],root[N];
int tot=; int pos[M];
int a[N];
int n,q; inline void copy(int x,int y){
Ls[x]=Ls[y];
Rs[x]=Rs[y];
sum[x]=sum[y];
} inline int bulidtree(int L,int R){
if (L>R) return ;
int k=tot++;
sum[k]=;
if (L==R) return k;
int mid=(L+R)>>;
Ls[k]=bulidtree(L,mid);
Rs[k]=bulidtree(mid+,R);
return k;
} inline int update(int o,int p,int v,int L,int R){
int k=tot++;
copy(k,o);
sum[k]+=v; if (L==R) return k; int mid=(L+R)>>;
if (p<=mid) Ls[k]=update(Ls[k],p,v,L,mid);
else Rs[k]=update(Rs[k],p,v,mid+,R); return k;
} inline int query(int o,int x,int y,int L,int R){
if (L==x && R==y) return sum[o];
int mid=(L+R)>>;
if (y<=mid) return query(Ls[o],x,y,L,mid);
else if (x>mid) return query(Rs[o],x,y,mid+,R);
else return query(Ls[o],x,mid,L,mid)+query(Rs[o],mid+,y,mid+,R);
} int main(){
scanf("%d",&n);
for (int i=;i<=n;i++) scanf("%d",a+i); root[]=bulidtree(,n); memset(pos,-,sizeof(pos));
for (int i=;i<=n;i++){
root[i]=root[i-];
if (~pos[a[i]])
root[i]=update(root[i],pos[a[i]],-,,n);
root[i]=update(root[i],i,,,n);
pos[a[i]]=i;
} scanf("%d",&q);
int x,y;
while (q--){
scanf("%d %d",&x, &y);
printf("%d\n",query(root[y],x,y,,n));
} return ;
}
离线树状数组
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <map>
#define ll long long using namespace std; const int N=;
const int Q=;
const int M=; struct query{
int L,R;
int id;
bool operator < (const query & t) const {
return R<t.R;
}
}q[Q]; int a[N];
int pos[M]={};
int ans[Q]; int c[N]; // 树状数组
int n; inline int lowbit(int x){
return x&(-x);
} inline void add(int x,int d){
while (x<=n) {
c[x]+=d;
x+=lowbit(x);
}
} inline int sum(int x){
int ret=;
while (x){
ret+=c[x];
x-=lowbit(x);
}
return ret;
} int main(){
scanf("%d",&n);
for (int i=;i<=n;i++) scanf("%d",a+i); int m;
scanf("%d",&m);
for (int i=;i<=m;i++) scanf("%d %d",&q[i].L, &q[i].R),q[i].id=i;
sort(q+,q++m); int j=;
for (int i=;i<=n;i++){
if (pos[a[i]]) add(pos[a[i]],-);
add(i,);
pos[a[i]]=i; while (j<=m && q[j].R==i){
ans[q[j].id]=sum(q[j].R)-sum(q[j].L-);
j++;
}
} for (int i=;i<=m;i++) printf("%d\n",ans[i]); return ;
}
SPOJ DQUERY D-query (在线主席树/ 离线树状数组)的更多相关文章
- SPOJ 3267 D-query(离散化+在线主席树 | 离线树状数组)
DQUERY - D-query #sorting #tree English Vietnamese Given a sequence of n numbers a1, a2, ..., an and ...
- SPOJ DQUERY - D-query (莫队算法|主席树|离线树状数组)
DQUERY - D-query Given a sequence of n numbers a1, a2, ..., an and a number of d-queries. A d-query ...
- hdu 4605 Magic Ball Game (在线主席树/离线树状数组)
版权声明:本文为博主原创文章,未经博主允许不得转载. hdu 4605 题意: 有一颗树,根节点为1,每一个节点要么有两个子节点,要么没有,每个节点都有一个权值wi .然后,有一个球,附带值x . 球 ...
- HDU 5869 Different GCD Subarray Query rmq+离线+数状数组
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5869 Different GCD Subarray Query Time Limit: 6000/3 ...
- bzoj 2434: 阿狸的打字机 fail树+离线树状数组
题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=2434 题解: 首先我们可以发现这个打字的过程本身就是在Trie上滚来滚去的过程 所以我们 ...
- 【SPOJ】375. Query on a tree(树链剖分)
http://www.spoj.com/problems/QTREE/ 这是按边分类的. 调试调到吐,对拍都查不出来,后来改了下造数据的,拍出来了.囧啊啊啊啊啊啊 时间都花在调试上了,打hld只用了半 ...
- Codeforces Round #345 (Div. 1) D - Zip-line 带单点修改的LIS 主席树 | 离线树状数组
D - Zip-line #include<bits/stdc++.h> #define LL long long #define fi first #define se second # ...
- BZOJ2120:数颜色(数状数组套主席树)(带修改的莫对)
墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2. R P ...
- 5.15 牛客挑战赛40 E 小V和gcd树 树链剖分 主席树 树状数组 根号分治
LINK:小V和gcd树 时限是8s 所以当时好多nq的暴力都能跑过. 考虑每次询问暴力 跳父亲 这样是nq的 4e8左右 随便过. 不过每次跳到某个点的时候需要得到边权 如果直接暴力gcd的话 nq ...
随机推荐
- 自动化测试断言Assent的使用
Assent 断言模板包含如下方法: assert.fail(actual, expected, message, operator) assert.ok(value, [message]) asse ...
- [HNOI2006]最短母串问题 AC自动机
题面:洛谷 题解: 如果我们对这些小串建出AC自动机,那么我们所求的大串就是要求满足遍历过所有AC自动机上的叶子节点,且经过步数最少的串.如果有多个步数相同的串,要输出字典序最小的串. 在AC自动机上 ...
- 利用Runloop优化流畅度
我们可以对runloop添加观察者,当观察到状态为kCFRunLoopExit,kCFRunLoopBeforeWaiting的时候,做一些耗时的处理,废话不说,直接上代码 - (void)viewD ...
- 洛谷 P2505 [HAOI2012]道路 解题报告
P2505 [HAOI2012]道路 题目描述 C国有n座城市,城市之间通过m条单向道路连接.一条路径被称为最短路,当且仅当不存在从它的起点到终点的另外一条路径总长度比它小.两条最短路不同,当且仅当它 ...
- Active Directory中获取域管理员权限的攻击方法
Active Directory中获取域管理员权限的攻击方法 译:by backlion 0x00 前言 攻击者可以通过多种方式在Active Directory中获得域管理员权限, ...
- js new date()说明
javaScript UTC() 方法: UTC() 方法可根据世界时返回 1970 年 1 月 1 日 到指定日期的毫秒数. 要创建一个一个日期对象,可以使用以下的方式: var now=new D ...
- [知识点]C++中STL容器之vector
零.STL目录 1.容器之map 2.容器之vector 3.容器之set 一.前言 关于STL和STL容器的概念参见STL系列第一篇——map(见上).今天介绍第二个成员——vector. 二.用途 ...
- java8系列
参见地址:https://segmentfault.com/a/1190000012211339
- bundle adjustment原理(1)转载
转自菠菜僵尸 http://www.cnblogs.com/shepherd2015/p/5848430.html bundle adjustment原理(1) 那些光束平差的工具,比如SBA.SSB ...
- 前端PHP入门-033-连接数据库-天龙八步
php检查MySQL的支持是否开启? 若没有看到mysqli扩展在windows服务器下,打开php.ini文件,将php_mysqli.dll打开即可! 注意: 从PHP7开始默认不再支持mysql ...