HDU 3244 完全背包 + 二分
本以为是道简单的二分,WA到哭。
本以为是道简单的二分,WA到哭。
给你一个序列,每次询问一个区间,问你区间内的Mex值。
什么是Mex值呢?比如说某个数字出现1次,某个数字出现3次,那么Mex就是:2.
这个类似于SG函数,就是未出现过的最小的那个数字。
另外输入中还会有另一种操作: 单点修改
我们肯定需要首先求出区间内每个数字出现的次数,然后再把这个次数存到一个数组中。求次数,不用说,莫队。但是单点修改需要用带修改莫队。需要注意的是,扩展区间的时候,要先扩展,再收缩,否则会出现下标为负数的情况。另外modify函数中,最后是交换两个数字,因为可能以后还得把他们换回来,所以不是赋值。
1 | #include <iostream> |
求的是某一段区间内小于等于K的数字的个数。
我们可以一开始输入的时候就把a[]和要询问的K存到一个b[]里,再求出a[]在b[]中的位置,建立n棵线段树,最后要求小于等于K的个数,实际上就是求第R棵线段树- 第L - 1棵线段树的那个线段树中区间端点的范围在1-K的总和。觉得这种方法很妙,大部分的题解都是用了二分。
1 |
|
和上面的几乎一样了。
1 |
|
比赛的时候想到用线段树存取每个区间前50大的数字,但是根本不知道怎么存,后来才知道用主席树,不用存,直接遍历50次查找前50大的就行!! 白学了主席树了。。。
兴高采烈地准备巩固一下莫队算法,没想到又碰到了离散化,兴高采烈的交上去,没想到因为一个符号,WA了20分钟。
区间问题,很快就想到莫队,原来还能用主席树做,奇妙。
乍一看觉得需要矩阵快速幂,但是还有区间询问的问题,所以需要用线段树+矩阵乘法。
对于任意的长度大于2的区间长度[L,R]的询问,有如下:
其中:
因此我们只需要用线段树维护区间内M(L+2)到M(R)的乘积,注意矩阵乘法的方向顺序。
因为query函数的问题,段错误N次. 还有注意数组的大小,太大也会段错误。
1 | #include <cstdio> |
用DP转移,复杂度为O(300N)
单调栈的经典例题,虽然单调栈的题目已经做过一些了,但是还是在这卡了一会。