P4137 Rmq Problem /mex 题意 给一个长为\(n(\le 10^5)\)的数列\(\{a\}\),有\(m(\le 10^5)\)个询问,每次询问区间的\(mex\) 可以莫队然后对值域分块,这样求\(mex\)的复杂度就正确了 一种更优的做法是按值域建可持久化线段树,对每个节点维护当前值域区间的最小出现位置,然后查询的时候就从\(r\)的那棵树一直尽量往左边走就好了 Code: #include <cstdio> #include <cstring> cons…
https://www.luogu.org/problemnew/show/P4137 只会log^2的带修主席树.. 看了题解,发现有高妙的一个log做法:权值线段树上,设数i对应的值ma[i]为数i首次出现的位置(没有出现就是n+1) 如果把询问按左端点排序,这样就转化为:修改:...:询问:询问[1,r]的答案 修改问题不大 询问[1,r]就转化为查询当前权值线段树上最小的数i,其对应的ma[i]>r:维护一下区间最大值,然后线段树上二分即可 可持久化一下线段树,还可以支持在线 ...好吧…
Code: #include<bits/stdc++.h> #define maxn 200001 using namespace std; void setIO(string s) { string in=s+".in"; freopen(in.c_str(),"r",stdin); } namespace tr { #define mid ((l+r)>>1) #define lson t[x].l #define rson t[x].r…
题面 首先,由于本人太菜,不会莫队,所以先采用主席树的做法: 离散化是必须环节,否则动态开点线段数都救不了你: 我们对于每个元素i,插入到1~(i-1)的主席树中,第i颗线段树(权值线段树)对于一个区间[l,r]维护的便是原序列1~i中的所有属于[l,r]的元素出现的最后位置的最小值: 当我们查询[x,y]时,我们查询第y颗线段树,找到第一个位置使得(出现的最后位置的最小值)比(x)要小: 然后恢复离散化之前的数值,然后输出: #include <bits/stdc++.h> #define…
题目描述 有一个长度为n的数组{a1,a2,…,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. 输入输出格式 输入格式: 第一行n,m. 第二行为n个数. 从第三行开始,每行一个询问l,r. 输出格式: 一行一个数,表示每个询问的答案. 输入输出样例 输入样例#1: 复制 5 5 2 1 0 2 1 3 3 2 3 2 4 1 2 3 5 输出样例#1: 复制 1 2 3 0 3 说明 对于30%的数据:1<=n,m<=1000 对于100%的数据:1<=n,m<=2…
正解:主席树 解题报告: 传送门$QwQ$ 本来以为是道入门无脑板子题,,,然后康了眼数据范围发现并没有我想像的那么简单昂$kk$ 这时候看到$n$的范围不大,显然考虑离散化?但是又感觉似乎布星?因为询问的是最小没有出现昂$kk$ 这时候考虑到答案显然要么是0要么是$a_{i}+1$?所以只用把$0,a_{i},a_{i}+1$离散化掉就成$QwQ$ 然后就主席树板子了$QwQ$?开权值线段树存这个位置当前最后一次出现的位置,然后每次就是找最小的最后一次出现位置<l的数就成$QwQ$ $over…
传送门 用主席树水莫队题…… 我们对于前缀和建立主席树,对于主席树中的每一个叶子节点表示它对应的数字最后出现的位置的编号,非叶子节点求左右节点的最小值,那么对于每一次询问$l,r$就是在第$r$棵主席树上找到权值$<l$的最左端的点,在主席树上二分即可. #include<bits/stdc++.h> #define mid ((l + r) >> 1) #define min(x,y) x < y ? x : y #define pushup(x) Tree[x].m…
题目 P4137 Rmq Problem / mex 解析 莫队算法维护mex, 往里添加数的时候,若添加的数等于\(mex\),\(mex\)就不能等于这个值了,就从这个数开始枚举找\(mex\):若不等于\(mex\),没有影响. 取出数的时候,如果这个数出现的次数变为了\(0\),\(mex\)就和这个数取一个\(min\) 代码 #include <bits/stdc++.h> using namespace std; const int N = 1e6 + 10; int n, m,…
题面:Rmq Problem / mex 题解: 先离散化,然后插一堆空白,大体就是如果(对于以a.data<b.data排序后的A)A[i-1].data+1!=A[i].data,则插一个空白叫做A[i-1].data+1, 开头和最尾也要这么插,意义是如果取不了A[i-1]了,最早能取的是啥数.要把这些空白也离散化然后扔主席树里啊. 主席树维护每个数A[i]出现的最晚位置(tree[i].data),查询时查询root[R]的树中最早的data<L的节点(这意味着该节点的下标离散化前代…
传送门 思路: 直接上主席树,对于每个询问\((l,r)\),我们在第\(r\)个版本的主席树中查询最晚出现的小于\(l\)最小的数就行了. 因为答案可能为\(a_i+1\),所以我们在离散化的时候考虑将\(a_i+1\)加进去. 一开始主席树部分没有思考清楚,还是对主席树的理解不够深入吧...其实就是一个维护前缀信息的数,后面的信息如果和前面有重复的,在这题中会直接将原来的覆盖掉.反正按照前缀树来思考就行啦~ #include <bits/stdc++.h> #define INF 0x3f…
一开始想的是莫队,然后维护几个bitset,然后瞎搞.脑子里想了想实现,发现并不好写. 还是主席树好写.我们维护一个权值的线段树,记录每一个权值的最后一次出现的位置下标.我们查询的时候要在前\(r\)颗线段树中找到第一个出现的位置下标小于\(l\)的数,在线段树上二分就行了. 这个想法还是非常巧妙的. #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include&…
洛谷题目传送门 YCB巨佬对此题有详细的讲解.%YCB%请点这里 思路分析 不能套用静态主席树的方法了.因为的\(N\)个线段树相互纠缠,一旦改了一个点,整个主席树统统都要改一遍...... 话说我真的快要忘了有一种数据结构,能支持单点修改,区间查询,更重要的是,常数优秀的它专门用来高效维护前缀和!!它就是-- !树状数组! 之前静态主席树要保存的每个线段树\([1,i]\),不也是一个庞大的前缀吗?于是,把树状数组套在线段树上,构成支持动态修改的主席树.每个树状数组的节点即为一个线段树的根节点…
区间mex问题,可以使用经典的记录上一次位置之后再上主席树解决. 不过主席树好像不是很好写哈,那我们写莫队吧 考虑每一次维护什么东西,首先记一个答案,同时开一个数组记录一下每一个数出现的次数. 然后些比较显然的性质:如果加入一个数时,答案只会增加:同样的删除一个数时,答案只会减小 利用好这些性质我们就愉快地上莫队即可不过复杂度很迷,转移的时候只能近似\(O(1)\) CODE #include<cstdio> #include<cctype> #include<cmath&g…
正解:主席树 解题报告: 先放下传送门QAQ 首先可以先思考如果只有一组询问,怎么解决 可以这么想,最开始一个数也麻油的时候能表示的最大的数是0嘛 然后先排个序,按顺序每次新加入一个数x,设加入这个数之前能表示的最大的数是y 首先显然的是如果x>y+1,y+1一定不能被表示出来,就GG了 如果x<=y+1,那么能表示出来的最大的数就一定是x+y,就更新一下y+=x 从上面这个式子我们可以得到实际上每加入一个数,当可以继续下去的时候其实就是y=∑x 然后现在考虑是有多组询问的鸭怎么搞呢QAQ?…
传送门 简单主席树啊. 但听说有随机算法可以秒掉%%%(本蒟蒻并不会) 直接维护值域内所有数的出现次数之和. 当这个值不大于区间总长度的一半时显然不存在合法的数. 这样在主席树上二分查值就行了. 代码: #include<bits/stdc++.h> #define N 500005 using namespace std; inline int read(){ int ans=0; char ch=getchar(); while(!isdigit(ch))ch=getchar(); whi…
P3939 数颜色 题目背景 大样例下发链接:http://pan.baidu.com/s/1c0LbQ2 密码:jigg 题目描述 小 C 的兔子不是雪白的,而是五彩缤纷的.每只兔子都有一种颜色,不同的兔子可能有 相同的颜色.小 C 把她标号从 1 到 n" role="presentation" style="position: relative;">nn 的n" role="presentation" style=…
题目传送门 任务查询系统 题目描述 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第Ei秒后结束(第Si秒和Ei秒任务也在运行),其优先级为Pi.同一时间可能有多个任务同时执行,它们的优先级可能相同,也可能不同.调度系统会经常向查询系统询问,第Xi秒正在运行的任务中,优先级最小的Ki个任务(即将任务按照优先级从小到大排序后取前Ki个)的优先级之和是多少.特别的…
//========================== 蒟蒻Macaulish:http://www.cnblogs.com/Macaulish/  转载要声明! //========================== 说好的“因为是OJ上的题,就简单点好了.”呢? 一开始看不懂,不会写. 然后跪了一个晚上决定看云的题解&……似乎是主席树套主席树!吓傻,还开了40000000的数组.然后一交tle…… 然后p是不可能玩常数的. 找不到其他做法. 然后找到了神牛dwjshift,好心地提供了题…
题面 传送门 题解 首先考虑一个贪心,我们把所有的人按\(a_i\)排个序,那么排序后的第一个人到\(k\),第二个人到\(k+1\),...,第\(i\)个人到\(k+i-1\),易证这样一定是最优的 然后发现这里有一个很重要的性质,\(a_i\)互不相同.那么就必定存在一个点\(mid\),在\(mid\)左边(包括\(mid\))的空格子和人一样多,右边(不包括\(mid\))也一样多 那么很明显,\(mid\)左边的所有人都需要往右跑,\(mid\)右边的所有人都需要往左跑 然后来康康答…
传送门 据说这题做法叫做可持久化trie树?(然而我并不会) 首先考虑一下贪心,从高位到低位枚举,如果能选1肯定比选0优 假设已经处理到了$b$的第$i$位,为1(为0的话同理就不说了) 那么只有当$a_j+x$的第$i$位为0时才能让答案的第$i$位为$1$ 考虑把$x$的影响去掉.如果当前的答案是$ans$(即令前面几位贪心情况下最大且第$i$位为0时的$a$),那么只有在区间$[ans-x,ans+(1<<i)-1-x]$的数能在加上$x$之后第$i$位为0(这个可以自己手动算一算) 如…
正解:主席树 解题报告: 传送门! 挺有趣的,至少我不会$QAQ$(虽然我不会的多了去了$QAQ$ 如果没有这个所谓美味度限制可以直接线段树水过去嘛$QwQ$ 然后现在问的是个异或运算后的结果,关于异或运算,然后还询问最大值,显然就很容易联想到,最大异或和 考虑把每个数做成二进制的形式,然后处理到第$i$位了,设做到第$i+1$位的时候确定的$maxans=as$,然后强制要求这一位是0(是1差不多的思考,一样儿的都$QwQ$),那就相当于是要求是否存在$[ans-x_{i},ans-x_{i}…
正解:主席树/动态点分治 解题报告: 传送门! $umm$淀粉质的话要是动态的我还不会$QAQ$,,,所以先写下主席树的题解昂$QwQ$ 题目大意是说,给定一棵树,树上每个点都有个值,然后有若干个询问,每次询问给定三个值,$(u,l,r)$,表示求值大小在$[l,r]$范围内的所有点到$u$点的距离之和是多少 考虑如果没有这个$[l,r]$的限制,就只是说,有若干个询问,每次给定一个$u$,问树上所有点到$u$的距离,怎么搞$QwQ$? 考虑固定一个点为根节点$rt$,预处理一个各个节点到根节点…
题面传送门 wssb,我紫菜 看到这类与最大值统计有关的问题可以很自然地想到分治,考虑对 \([l,r]\) 进行分治,求出对于所有 \(l\le x\le y\le r\) 的点对 \((x,y)\) 的贡献之和.若 \(l=r\) 那只有 \(a_l=1\) 的情况会产生贡献,特判一下并直接返回即可.若 \(l\ne r\),我们假设 \([l,r]\) 中最大值的位置为 \(mid\),考虑将所有符合要求的点对分成三部分,一是 \(l\le x\le y<mid\),二是 \(mid<x…
目录 链接 思路 线段树 莫队 链接 https://www.luogu.org/problemnew/show/P4137 思路 做了好几次,每次都得想一会,再记录一下 可持久化权值线段树 区间出现存最小的下标 然后线段树上二分 如果左边min>L 那就去右边 因为左边都被[L,R]占满了 虽然比卡常的莫队慢好多(700ms和1000ms) 但是理论上快哇 线段树 // luogu-judger-enable-o2 #include <bits/stdc++.h> using name…
题目链接:https://www.luogu.org/problemnew/show/P4137 求区间内最大没出现过的自然数 在add时要先判断会不会对当前答案产生影响,如果有就去找下一个答案. #include <cstdio> #include <algorithm> #include <iostream> #include <cmath> using namespace std; ; , curR = , n, m, a[maxn], answer…
Code: #include <cstdio> #include <algorithm> #include <cstring> #include <string> #include <vector> using namespace std; void setIO(string a) { string in=a+".in",out=a+".out"; freopen(in.c_str(),"r&qu…
题面:P4137 Rmq Problem / mex 题解:先莫队排序一波,然后对权值进行分块,找出第一个没有填满的块,直接for一遍找答案. 除了bzoj3339以外,另外两道题Ai范围都是1e9.显然最劣情况下答案是N,所以大于N的Ai都直接无视就可以. 由于求的是最小的自然数,自然数包括0,所以要额外处理一下含有0的块.我这里是直接把0拖出来放在第0块了. 代码: #include<cstdio> #include<cstring> #include<iostream&…
P4137 Rmq Problem / mex 题目描述 有一个长度为n的数组{a1,a2,-,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. 输入输出格式 输入格式: 第一行n,m. 第二行为n个数. 从第三行开始,每行一个询问l,r. 输出格式: 一行一个数,表示每个询问的答案. 输入输出样例 输入样例#1: 5 5 2 1 0 2 1 3 3 2 3 2 4 1 2 3 5 输出样例#1: 1 2 3 0 3 说明 对于30%的数据:1<=n,m<=1000 对于100%的…
[Luogu4137]Rmq Problem/mex (莫队) 题面 洛谷 题解 裸的莫队 暴力跳\(ans\)就能\(AC\) 考虑复杂度有保证的做法 每次计算的时候把数字按照大小也分块 每次就枚举答案在哪一块里面就好 #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm>…
BZOJ3339&&3585:Rmq Problem&&mex Description 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. Input 第一行n,m. 第二行为n个数. 从第三行开始,每行一个询问l,r. Output 一行一个数,表示每个询问的答案. Sample Input 5 5 2 1 0 2 1 3 3 2 3 2 4 1 2 3 5 Sample Output 1 2 3 0 3 HINT 数据…