【洛谷P4137】Rmq Problem / mex【主席树】

2024-01-30 10:18
文章标签 mex 洛谷 problem rmq 主席 p4137

本文主要是介绍【洛谷P4137】Rmq Problem / mex【主席树】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目大意:

题目链接:https://www.luogu.org/problemnew/show/P4137
有一个长度为 n n n的数组 { a 1 , a 2 , … , a n } \{a1,a2,…,an\} {a1,a2,,an} m m m次询问,每次询问一个区间内最小没有出现过的自然数。


思路:

显然主席树。
对于第 k k k棵线段树,设叶子节点 i i i表示在数列前 k k k个数字中,数字 i i i出现的最后位置。
显然 a [ ] a[] a[]的范围是吓人的。最终答案一定不会 > n + 1 >n+1 >n+1,所以读入到 x ( x > n ) x(x>n) x(x>n)之后直接把 x x x变成 n + 1 n+1 n+1就可以了。
对于任意一个询问 x , y x,y x,y,意思就是说在第y棵线段树中找到第一个叶子结点最后出现的位置<l
可以在任意区间 [ l , r ] [l,r] [l,r]中记录 m i n min min表示 [ l , r ] [l,r] [l,r]中最后出现位置最前的位置。
那么对于任意区间,如果左儿子 m i n min min小于 l l l,答案就在左边,否则在右边。
时间复杂度 O ( n l o g n ) O(n\ log\ n) O(n log n)


代码:

#include <cstdio>
#include <algorithm>
using namespace std;const int N=200010;
int n,T,tot,x,y,root[N];struct Tree
{int ls,rs,last,min;
}tree[N+N*20];int build(int l,int r)
{int p=++tot;if (l==r) return p;int mid=(l+r)/2;tree[p].ls=build(l,mid);tree[p].rs=build(mid+1,r);return p;
}int insert(int now,int l,int r,int x,int val)
{int p=++tot;tree[p]=tree[now];if (l==r){tree[p].last=tree[p].min=val;return p;}int mid=(l+r)/2;if (x<=mid) tree[p].ls=insert(tree[now].ls,l,mid,x,val);else tree[p].rs=insert(tree[now].rs,mid+1,r,x,val);tree[p].min=min(tree[tree[p].ls].min,tree[tree[p].rs].min);return p;
}int ask(int x,int l,int r,int val)
{if (l==r) return r;  //找到答案int mid=(l+r)/2;if (tree[tree[x].ls].min>=val) return ask(tree[x].rs,mid+1,r,val);else return ask(tree[x].ls,l,mid,val); 
}int main()
{scanf("%d%d",&n,&T);root[0]=build(0,n);for (int i=1;i<=n;i++){scanf("%d",&x);if (x<=n) root[i]=insert(root[i-1],0,n,x,i);  //插入else root[i]=insert(root[i-1],0,n,n+1,i);}while (T--){scanf("%d%d",&x,&y);printf("%d\n",ask(root[y],0,n,x)); }return 0;
}

这篇关于【洛谷P4137】Rmq Problem / mex【主席树】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/659923

相关文章

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

uva 10025 The ? 1 ? 2 ? ... ? n = k problem(数学)

题意是    ?  1  ?  2  ?  ...  ?  n = k 式子中给k,? 处可以填 + 也可以填 - ,问最小满足条件的n。 e.g k = 12  - 1 + 2 + 3 + 4 + 5 + 6 - 7 = 12 with n = 7。 先给证明,令 S(n) = 1 + 2 + 3 + 4 + 5 + .... + n 暴搜n,搜出当 S(n) >=

高精度计算(代码加解析,洛谷p1601,p1303)除法待更新

目录 高精度加法 高精度减法 高精度乘法 高精度加法 我们知道在c++语言中任何数据类型都有一定的表示范围。当两个被加数很大时,正常加法不能得到精确解。在小学,我们做加法都采用竖式方法。那么我们也只需要按照加法进位的方式就能得到最终解。 8 5 6+ 2 5 5-------1 1 1 1 加法进位: c[i] = a[i] + b[i];if(c[i] >=

洛谷 凸多边形划分

T282062 凸多边形的划分 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 先整一个半成品,高精度过两天复习一下补上 #include <iostream>#include <algorithm>#include <set>#include <cstring>#include <string>#include <vector>#include <map>

能量项链,洛谷

解释:  环形dp问题还是考虑将环拉直,可以参考我上一篇文章:环形石子合并 [2 3 5 10 2] 3 5 10 将环拉直,[]内是一个有效的区间,可以模拟吸收珠子的过程,         如[2 3 5] <=>(2,3)(3,5)    2是头,3是中间,5是尾 len >= 3:因为最后[2 10 2]是最小的可以合并的有效区间 len <= n + 1因为[2 3

11991 - Easy Problem from Rujia Liu?

题意: 输入一串整型数列,再输入两个数k,v,输出第k个v的序号。不存在则输出0,如第一个样例 8 41 3 2 2 4 3 2 11 3 //第1个3,序号为2,输出22 4 //第2个4,不存在,输出03 2 //第3个2,序号为7,输出74 2 思路: struct num {

HDU 1016 Prime Ring Problem (深搜)

OJ题目 : click here ~~ 大概题意:n个数,形成一个环,使得相邻两个数的和为素数。以1开始,按字典序输出序列。 很简单的深搜。 AC_CODE int n;int visit[22];int num[22];int len;bool Is_prime(int x){for(int i = 2;i*i <= x;i++)if(x%i == 0) return

LVM 'Can’t open /dev/sdb1 exclusively. Mounted filesystem?' Problem

在将几块盘做LVM时,遇到一个之前都没遇到过的问题: root@ubuntu:~# pvcreate /dev/sdc1Can't open /dev/sdc1 exclusively. Mounted filesystem? 首先第一反应就是查看这个分区是否已经在使用了,但是没有。 查看硬盘的一些信息: root@ubuntu:~# cat /proc/partitionsmajo

洛谷P5490扫描线

0是最小的数字,将一个线段看成一个区间,对于一个矩形,从下扫到上,入边为1,而出边为-1,意思是将这个区间上的所有点加1(区间修改).把线段表示为Line[i],其中记录了l,r,h,tag,左右端点,高度,入边还是出边(1或-1) 那么每次区间修改后不为0的区间它的值可能是1,2,3或者是其它数字,这不好统计,可以将它转化一下,0是不是表示没有被覆盖过的地方,我们只要统计0的个数然后用总长减去

【POJ】2104 K-th Number 静态第K小——主席树

传送门:【POJ】2104 K-th Number 题目分析: 哇咔咔,又get了一个新技能——主席树,初步学习主席树,一次AC,感觉好棒~ 也在此Orz一下发明者主席——fotile96,在叉姐群经常看到主席的身影,不过蒟蒻也只能仰望神犇的背影了,起步迟且天赋不如人,只能慢慢的走下去,希望有一天能看到另一个世界。 主席树的编程方式是函数式编程(可持久化),保证我们可以查询历史