【T1】 这题实际上是大水题……但是脑抽忽略了DP的阶段性特征,而且明明已经写好了搜索却没有想到直接改记忆化……讲的是对于 [1,n] 的数的所有排列,有 m 个限制,即令某个数要在另一个数后面,问如果违反最多k个限制,存在多少种方案数,这里用搜索的思路先推一个暴力,记下目前选了的点,同时违反了 j 个限制,然后一个记忆化令f(i,j)中 i 为选了哪些点,用二进制数来记,那么时间复杂度为O(2nn2k)。稍微优化下,如果利用位运算,考虑到没有两个相同的限制,令 d(k) 为需要在目前枚举到要选的 k 后面的点(限制),i&f(k)中1的个数就是违反的限制。这时复杂度只有 O(2nnk) 。 另外这题或许可以找强连通分量然后各种组合数学讨论?也许这样可以让范围更大点。 【T2】 先叙述下题意 解法1:考虑到这道题有这么多区间,就上分治。考虑区间 [l,r] ,先算出 f[l,mid] 和 f[mid+1,r] ,然后算跨越中点的方案数。 我们先将跨越中点的区间分成左右两段,即左端点到 mid 和 mid+1 到右端点,然后我们分类讨论 max 和 min 所对应的数在哪一边,根据对称性不妨只对两种情况讨论,即 max 和 min 的对应点都在左边,和 max 对应在左 min 对应在右。情况1和2,都可以化成类似的情况,枚举左端点 i ,然后考虑[i,mid]的 max 和 min ,然后对于另一边,先找两个分别包含右区间第一项的相应维护两个指针,一个 j1 到右区间的某个端点表示满足要求的右端点的取值区间(在 min 的约束下),一个 j2 类似地维护在 max 约束下的取值区间。稍微解释下这两个指针的做法,是因为单调性,因为当 i 越往左移,对应的max越大, min 越小,这两个指针也具有相应的移动方向单调。那么剩下的情况只要算一算就好了……(讨论起来特别麻烦) 解法2:这是在考场上想到的做法……我们差分一下,令 f(i) 表示 i 对答案的贡献,实质上就是所有以i为右端点的区间的最小值与最大值的积和。 那么我们考虑一下,如同解法1中的思路,我们考虑找一个 j1 ,,令 aj1>ai 且 j1 最大,即最靠近 i 。然后相应找一个aj2<ai的 [j,i] ,显然和 f(min{j1,j2}) 中的应该是一样的……(诶不对,先打住,占个坑以后补,好像前后逻辑关系反了) 【T3】 这题很劲啊,竟然是对随机数的稳定排序的期望……完全不会 不过解法很妙啊 先来描述下题意,就是用稳定排序排序若干个数 ai ,而 ai 是在 [li,ri] 区间内随机生成的一个整数,设排序完后 ai 的排名 pi ,且每个 ai 带有一个权值 si ,求 E[∑i=1nsipi] 。 先给几个数据范围: 对于40%的数据,n<=10,0<=li<=ri<=20 对于60%的数据,0<=li<=ri<=1000 对于100%的数据,n<=10^5,0<=li<=ri<=10^9,0<=si<=10^9 题意的实质是求每个数前期望不大于这个数(稳定排序),后期望有多少个数比这个数小,所以我们根据对称性先求每个数前面的部分,后面的倒过来再扫一遍就行了,两边是互相独立的。 考虑40%,可以用下DP,我们设 fi,j,k 表示 i 前面有j个数小于等于 ai=k ,然后直接做就行,还可以顺手省掉1维空间。时间复杂度 O(n3L) 考虑60%,我们来建一个桶,扫的时候顺便记录下这个数对后面的数的期望的贡献。我们容易算出这个数再每个取值上都对后面(就是比它大的数)数的排名有 1ri−li+1 的期望值的贡献,于是综合考虑下(因为是整数),一个在 [li,ri] 间范围的数对于桶的贡献,相当于在桶中 [li,ri] 处加了一条直线(换句话说,等差数列),在 ri 以后,则增加值相当于 ri 处的增加。这里暴力维护即可。 其实100%算法和60%的非常接近,我们只要注意到区间加等差数列是容易用线段树维护的。我们维护一个公差 d 和首项a,下传标记的时候对于左子节点下传 d 和a,对于右子节点下传 d 和a mid×d,合并标记(就是把下传的标记与当前标记合并)的时候,注意到 [a,a+d,a+2d,⋯]+[a′,a′+d′,a′+2d′,⋯]=[a+a′,(a+a′)+(d+d′),(a+a′)+2(d+d′),⋯] ,直接把 d 和a对应地加起来就行了。更新当前节点信息的时候运用等差数列求和即可,不难得出。于是我们现在只要正着倒着扫一遍,每次求 [li,ri] 范围的和,然后更新的时候加一个等差数列就可以了。需要注意的是,这棵线段树显然不能开权值的范围,而应该离散化或是动态申请(维护内存池)。运用期望的线性性质直接加一块就行了。 还有一种线段树的解法,只要注意到等差数列的差分是相等的,那么我们只需要对桶差分,然后我们立即发现这就是一个区间加修改与区间和查询的经典线段树……直接做就好了。 另外提到下题解中最后的问题,就是把整数域换为实数域,这种时候只要积分一下期望得到所加上去的不是等差数列,而是等差数列的平方,那么由平方的性质,我们可以差分两次然后就做完了。
