版权声明:本文为博主原创文章,未经博主允许不得转载。

SPOJ DQUERY

题意:

  给出一串数,询问[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 (在线主席树/ 离线树状数组)的更多相关文章

  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 (莫队算法|主席树|离线树状数组)

    DQUERY - D-query Given a sequence of n numbers a1, a2, ..., an and a number of d-queries. A d-query ...

  3. hdu 4605 Magic Ball Game (在线主席树/离线树状数组)

    版权声明:本文为博主原创文章,未经博主允许不得转载. hdu 4605 题意: 有一颗树,根节点为1,每一个节点要么有两个子节点,要么没有,每个节点都有一个权值wi .然后,有一个球,附带值x . 球 ...

  4. HDU 5869 Different GCD Subarray Query rmq+离线+数状数组

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5869 Different GCD Subarray Query Time Limit: 6000/3 ...

  5. bzoj 2434: 阿狸的打字机 fail树+离线树状数组

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=2434 题解: 首先我们可以发现这个打字的过程本身就是在Trie上滚来滚去的过程 所以我们 ...

  6. 【SPOJ】375. Query on a tree(树链剖分)

    http://www.spoj.com/problems/QTREE/ 这是按边分类的. 调试调到吐,对拍都查不出来,后来改了下造数据的,拍出来了.囧啊啊啊啊啊啊 时间都花在调试上了,打hld只用了半 ...

  7. 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 # ...

  8. BZOJ2120:数颜色(数状数组套主席树)(带修改的莫对)

    墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2. R P ...

  9. 5.15 牛客挑战赛40 E 小V和gcd树 树链剖分 主席树 树状数组 根号分治

    LINK:小V和gcd树 时限是8s 所以当时好多nq的暴力都能跑过. 考虑每次询问暴力 跳父亲 这样是nq的 4e8左右 随便过. 不过每次跳到某个点的时候需要得到边权 如果直接暴力gcd的话 nq ...

随机推荐

  1. 在Linux上编译使用tcmalloc

    项目需要使用tcmalloc,比较简单的方法是安装tcmalloc相关包(gpertools)后,将tcmalloc的静态库提取出来,在编译项目内核(执行makefile)时,链接上静态库即可. 这里 ...

  2. String Problem HDU - 3374(最大最小表示法+循环节)

    题意: 给出一个字符串,问这个字符串经过移动后的字典序最小的字符串的首字符位置和字典序最大的字符串的首字符的位置,和能出现多少次最小字典序的字符串和最大字典序的字符串 解析: 能出现多少次就是求整个字 ...

  3. 【转】c# thread.join 理解

    转自:http://blog.csdn.net/lulu_jiang/article/details/6584251 线程Join()方法:让一个线程等待另一线程终结后再继续运行. private s ...

  4. 【BZOJ4184】shallot(线段树分治,线性基)

    [BZOJ4184]shallot(线段树分治,线性基) 题面 权限题啊.....好烦.. Description 小苗去市场上买了一捆小葱苗,她突然一时兴起,于是她在每颗小葱苗上写上一个数字,然后把 ...

  5. 【BZOJ5319】军训列队(主席树)

    [BZOJ5319]军训列队(主席树) 题面 BZOJ 洛谷 题解 一眼题既视感... 首先很明显,每次询问的结果显然是做一次离散. 然后直接上主席树就好了... 查询答案的方式也很简单 考虑一下那个 ...

  6. smarty调用php函数

    模板书写: {'param1'|functionName:'param2':'param3'} php函数原型: echo functionName('param1','param2','param3 ...

  7. 阿里云 centos7 tomcat 启动巨慢的解决方法(几分钟)

    方法一: 通过修改Tomcat启动文件-Djava.security.egd=file:/dev/urandom 通过修改JRE中的java.security文件securerandom.source ...

  8. mysql 查看服务器正在运行的进程

    有时候遇到mysql突然很久没有响应的情况,我们就想知道背后发生了什么. 这时候我们就可以通过以下的命令来查看mysql正在处理的进程: show processlist; 这个命令可以通过navic ...

  9. springMVC参数的获取区别

    在springMVC中我们一般使用注解的形式来完成web项目,但是如果不明白springmvc的对于不同注解的应用场景就会很容易犯错误 1.什么是restful形式: 什么是RESTful restf ...

  10. 抓包 ------ Wireshark 的使用

    Wireshark的数据包详情窗口,如果是用中括号[]括起来的,表示注释,在数据包中不占字节 发了一个包,很久没有收到应答后,会重发包,在Wireshark抓包工具提示“[TCP Retransmis ...