NOI2017

整数(线段树)

不难想到按位处理,位数比较多考虑使用动态开点线段树维护大数,那么复杂度是\(O(nlog^2n)\)的,不够优秀。

但注意到我们需要支持的是二进制下的加减法,而在二进制下我们可以使用int压位来节约时空,于是使用unsigned int压32位,再用线段树维护。这样每一次加减都只会影响到最多两个位置,复杂度可以降为\(O(nlogn)\)。线段树需要支持单点查询、区间查询是否全\(0\)或全\(1\)(这是为了在进退位的时候二分出进退位的影响范围)、区间覆盖。直接做就可以了。

代码

蚯蚓排队(哈希)

\(7.5 \times 10^8\)\(2s\) emmm

因为每一次询问的串长不会超过\(50\),所以我们考虑在拼接和分离的时候动态维护长度为\(1\)\(50\)的所有串。

因为每一次拼接和分离都只会加入/删除个数为\(k^2\)级别的串,所以暴力维护一下它们的Hash值,每一次询问的时候也暴力搞出每一个子串的Hash值,然后在哈希表上查一下。

复杂度\(O(k^2m)\)。卡常方法:哈希表手写、链表手写、自然溢出、\(seed=19491001\)……

代码

泳池(概率、DP、线性递推)

首先恰好为\(k\)可以转化为\(\leq k\)的概率-\(\leq k - 1\)的概率。

\(f_i\)表示宽度为\(i\)、底部最右边第\(i\)个点一定被ban、最大的无ban块矩形\(\leq k\)的概率,枚举底部从右往左第二个被ban的块,有\(f_0 = 1 , f_i = (1-q)\sum\limits_{j=1}^{\min\{k , i\}} f_{i-j} p_{j-1}\),其中\(p_{j-1}\)是宽度为\(j\)、底部没有被ban的块、最大无\(ban\)块矩形\(\leq k\)的概率。这样\(\leq k\)的概率就是\(\frac{f_{n+1}}{1-q}\),因为第\(n+1\)列的被ban的块的概率要除掉。

注意到上面是一个线性递推,只需求出\(p_1,...,p_k\)就可以\(O(k^2logn)\)或者\(O(klogklogn)\)地求解。

\(p_i\)考虑一个DP:设\(dp_{i,j}\)表示对于一个宽度为\(i\)的矩形,其底部\(j\)行不存在ban块,第\(j+1\)行一定存在ban块,最大无ban块\(\leq k\)的概率。那么\(p_i = \sum\limits_{j=1}^{+\infty} dp_{i,j}\)

\(dp\)数组转移枚举从左往右第一个ban块在第几列,有\(dp_{i,j} = q^j(1-q) \sum\limits_{k=1}^i (\sum\limits_{l > j} dp_{k-1,l}) (\sum\limits_{l \geq j}dp_{i-k , l})\),边界为\(dp_{0,x} = 1 , x \in [1 , k]\)。有效的\(dp_{i,j}\)会满足\(ij \leq k\),所以有效位置是\(O(klogk)\)级别的,故上面转移可以后缀和优化至\(O(k^2logk)\),(或许?)可以FFT优化到\(O(klog^2k)\)

但是似乎这道题强上多项式和暴力没什么特别大的区别

代码

游戏(2-SAT)

第一眼看上去似乎是一个3-SAT问题,然而\(d \leq 8\)给我们的信息就是暴力枚举。枚举\(x\)型地图变成\(a\)型地图还是\(b\)型地图(实际上不要枚举\(c\),因为\(ab\)两种地图已经包含了选择\(ABC\)三辆车的情况),对于每一种情况跑2-SAT。复杂度\(O(2^d(n+m))\)

然后需要用一些玄学的随机和疯狂叉人的test12345看不懂的2-SAT写法

代码

蔬菜(贪心、并查集)

使用增量法求解答案,即每一次增加一天然后考虑新增加的蔬菜的最大价值,因为之前被加入到售卖行列的蔬菜在天数增加之后也一定会在售卖行列里。考虑现在正在做有\(i\)天的最大收益。

首先,一个价值更高的蔬菜肯定会优先被安排位置。所以我们把所有蔬菜全部丢到一个堆里面,对于\(s_i\),我们从每一种蔬菜中单独拿出一个蔬菜,特殊处理一下它的腐坏时间,也作为一个对象放到堆里。每一次我们从堆顶取出价值最大的蔬菜看它是否有位置。安排\(m\)个蔬菜进入到售卖行列或者堆为空时就完成了一次增量。

对于一个蔬菜,为了给之后的蔬菜腾出位置,肯定安排在越后面越好。我们算出这种蔬菜最后能安排在哪天(要跟\(10^5\)取min),我们要求的就是这一天前距离这一天最近且蔬菜没有被安排满的天是哪一天。可以使用并查集完成:每当某一天的蔬菜被安排满了之后就把它的父亲指向前一天,那么当前点的并查集的根就是第一个没有被安排满的天数。

最后,注意到上面的贪心是对于\(10^5\)天而言的,也就是说如果能够安排在第\(10^5\)天就一定会安排在第\(10^5\)天,但是实际上并没有那么多天。但这样的贪心是正确的,考虑:如果某一个蔬菜被安排在了第\(x+1\)天,而第\(x\)天的蔬菜没有满,那么放在第\(x\)天也是可行的。因为蔬菜数量一定不会超过\(iM\),所以我们可以把所有蔬菜全部推到前\(i\)天,也就相当于求出了有\(i\)天时的最大收益。

代码

分身术

posted @ 2019-05-06 10:31  cjoier_Itst  阅读(516)  评论(3编辑  收藏  举报