1、【luogu4921】情侣,给我烧了:
我们这里只讨论直接算代替容斥的做法。
$n$个情侣,恰好有$k$个不和谐,枚举是哪$k$个,$C_n^k$。
坐在哪些位置上,$C_n^k$。
确定先后关系(为下面算$f$埋下伏笔),$2^n$。
确定顺序,$k! (n-k)!$。
剩下还要求$i$对情侣,已经指定了顺序,和彼此先后关系,求任意一对都不坐在一排上的方案数。
也就是说对于任意一种方案,我们都可以唯一确定它的顺序和彼此的先后关系,因为我已经乘过了。
考虑顺序和彼此先后关系怎么体现:也就是说,对于“$i$对情侣任意一对都不坐在一排上”的情况,我们怎么规定它的“顺序”和“彼此先后关系”。
这就很难了,我试了很多种方法,只有一种方法能得到递推式:
不同排从右到左,同一排从下往上。以这样的顺序扫到的第一个记为$x'$,扫到的第二个记为$x$,彼此的先后关系是$x'$和$x$的先后关系、顺序是$1',2',3'...n'$的顺序。
每次在右下角加入$n'$,显然,右上角应该填$n-1'$。
然后考虑$n$和$n-1$是不是在同一排上,如果是,就把这一排抽去,就是$f[n-2]$,因为$n$和$n-1$可以互换位置,考虑可以插在任意的位置,所以就是$2(n-1)f[n-2]$,
如果不是,想的有点麻烦。但其实答案不麻烦,可以把$n$,$n-1$看成一对情侣,“大型四角恋直播现场(没准还是同性)”,$n-1$的情况下,指定一对情侣,让一个当$n$,另一个当$n-1$,或者让另一个当$n$,一个当$n-1$,这样的话,答案就是$2(n-1)f[n-1]$。所以总的递推式$$f[n]=2(n-1)(f[n-1]+f[n-2])$$
这道题是我先看了题解,但是没有看懂,以答案反推过程的做出来的,即使这样,还是花费了我$4$天的时间,如果让我自己想我肯定是想不出来的。
2、【BZOJ3142】【HNOI2013】数列
记录一下我的错误的思路
对股价的数组做差分,设差分数组为$D$,记$D$的$k-1$项的和为$sum$,枚举$sum$,有$$ans=sum_{k-1}^{n}{(n-sum)F(sum-k+1,k-1)}$$,其中,$F(x,y)$表示把$x$个球放到$y$个不同的盒子里,并且每个盒子里的数不超过$m-1$的方案数,但是$F$不能快速的求出来,所以这样是假的。
题解的思路很好,假设差分后的数组的和为$sum$,贡献为$n-sum$不假,即求$sum{n-sum}$,我们把这个和式的两项分别考虑,
对于$n$,方案数共有$m^{k-1}$种,所以这一项展开就是$n*m^{k-1}$,
对于$sum$,求得就是每个$D$数组的和的和。我们拆成每一个值$x$考虑,因为都有可能,所以$x$的贡献是$$frac{m^{k-1}(k-1)}{m} x$$,化成一个等差数列和的形式,就可以了。
这个方法能成立的关键的条件就是有“这些参数满足$m(k-1)<n$”。
3、【BZOJ5323】【JXOI2018】游戏
一道永军级别的概率题。
考虑一个最傻逼的暴力,从后往前考虑,假设剩下的长度为$n$,每次把限制掉的排列个数乘$n$,再更新成剩下来的。
估计还能优化,但是已经可以过了。。。
组合数学部分今天就到这里,下面我们进入数据结构阶段。
4、【HEOI2013】ALO
考虑每个点$x$,要是想和$y$异或,必须满足$x$不是全局最大值,并且到$y$的路径上比自己大的不能超过$1$个。用单调栈$set$确定一个区间(犹如“开车旅行”),在区间里查异或最大就可以了。
5、【FJOI2015】火星商店问题
简化一下题意,两个维度:时间和序列(位置),每次一个矩形内查点的异或最大。
线段树分治的题,我可能要学一下了。这一方面我学的的确没有$aysn$好。
用来分治的线段树是对时间开的,询问的时间是一个区间的形式,每次新建的点却是一个点的形式。
我们把点加在线段树上,线段树的每个节点可以开个$vector$存,在一个节点的$vector$内是可以直接排序的,因为时间上的限制已经被考虑了,我们直接在这上面建可持久化$01-trie$树即可,这样时间和空间都是两个$log$的(甚至可以只在最底建可持久化$01-trie$,然后用线段树合并,这样可能空间复杂度会好一些)
这个线段树是不能$pushdown$的(如果暴力用线段树合并复杂度会假掉),也就不能支持新建的点是一个区间的形式。
上面是我的方法,我看了$yyb$的代码,发现它既没有用线段树合并、也没有空间两个$log$,神奇的发现,我们不如直接把区间加在线段树上,然后从上到下考虑,到一个区间时,把这个区间对应的点拎出来建一棵$01-trie$树,这样空间复杂度就能少个$log$了,其实本质是一样的。
6、【BZOJ2989】数列
二进制分组或者$CDQ$分治。
看到这个$Query$的形式,不如把修改理解为:加一个$(x,k)$的点。
然后查的东西可以曼哈顿距离转切比雪夫距离,就是查一个正方形内的点的个数,可以用主席树做。
先讲二进制分组的做法。二进制分组是可以做到在线的。维护所有的点集,到加入点的时候就二进制分组就行了,然后等于前一个的时候就把两个都拿出来暴力重建主席树,查询的时候依次查每一个组就行了。复杂度是两个$log$的。
$CDQ$分治的做法也很简单,肯定是要离线的。思想就是对时间分治,先要把初始的点按插入操作补全,每次考虑前一半的修改对后一半的查询的贡献,我们把前一半按$x$坐标排序,然后把矩形分成左边界和右边界,每次插入一个点,遇到边界就查询,就可以了。这个复杂度也是两个$log$的,但是常数会小一些。
以上皆属于口胡,坐等$aysn D$我。
7、【ZJOI2013】K大数查询
$aysn$推荐的神仙题,他用整体二分做的。
一开始以为是可以用主席树做的,定睛一看发现操作是区间加,得,我老老实实学整体二分。
我假了,读错题了,不是区间加,是集合中添加一个元素。
整体二分,当然是二分答案。
何谓整体二分?就是直接一起二分所有的询问操作的答案,然后暴力扫描当前操作区间,将其划分为答案的左子区间与右子区间两个部分。
那么以什么为划分依据呢?看看这个操作对于左子区间有没有贡献。如果没有,那么就划分到右子区间中,然后将这个操作的权值更改为这个贡献减去所需的贡献,反之,则划分到左子区间中,同时将这个操作的贡献加入某一个容器,为询问操作服务。
——摘自洛谷题解第一篇,$orz dalao$
首先肯定要二分答案,而且检验的过程的操作次数是要和当前二分值域集合里的元素个数是有关的,这点和$CDQ$分治的要求是一样的。
$solve(st,en,l,r)$表示假设当前的修改/查询集合为$q[st..en]$,并且把值域确定在了$[l..r]$范围内,进一步缩小他们的答案范围的过程。
第$k$大就是有$k-1$个比它大,所以我们只要关心比$mid$大的元素个数就好了。
二分一个$mid$,我们要把询问分成$ans<=mid$和$ans>mid$,
对于增加操作,如果增加的比$mid$大,会对前后都产生影响,但是我们把它放到后面去(这点在查询的时候再说),并且把$[l..r]$区间$+1$,表示已经有这些数比$k$大了,反之,直接把它放到前面(肯定不会对后面产生影响),什么都不做。
对于查询操作,查一下当前的区间里的元素个数$val$是不是大于$c$,如果是,应该放到后边。如果不是,为了消除“对于增加操作,如果增加的比$mid$大”带来的影响,我们把它的$c$减去$val$,然后在放到前面。