zoukankan      html  css  js  c++  java
  • 一个计数问题(cf1295F)

    Educational Codeforces Round 81 Problem F. Good Contest

    题意

    一个长度为(n)的整数数列,第(i)个元素在([l_i, r_i])里均匀随机,求它单调不增的概率。由于答案是个有理数,输出它在模(998244353)下的值。

    题面里定义的inversion很奇怪,所以我一开始把它看成单调不减了,测样例才发现。不过也没关系,把序列翻转一下就行,后面就按单调不减写了。

    (l_i, r_i)的范围很大:(0 leq l_i leq r_i leq 998244351),仅仅让作为分母的(r_i-l_i+1)不达到(998244353)以保证逆元存在。(n leq 50)

    观察

    首先考虑朴素的dp:(dp[i][j])表示第(i)个元素是(j),并且以它为结尾的前缀单调不减的方案数,转移是平凡的:(dp[i][j]=sum_{l_{i-1} leq k leq j} dp[i-1][k])

    注意到(n)不是很大,那么离散化之后值域就被分成了(O(n))段。按这个思路做下去的话,就是要考虑每一段中的dp值有什么性质,一起处理。为了找到这个性质,首先观察一个简单的情况:所有区间均相同,(l=0)(r)充分大。这时考虑差分,(dp[i][j])就是将(j)拆分为(i)个非负整数之和的方案数了,即(dp[i][j]=egin{pmatrix} j+i-1 \ i-1 end{pmatrix})

    再考虑上面的dp转移,这提示我们用到组合数的这个性质:(sum_{k=0}^r egin{pmatrix} t+k \ t end{pmatrix} = egin{pmatrix} t+r+1 \ t+1 end{pmatrix}),这意味着如果值域中某一段的dp值为(egin{pmatrix} t \ t end{pmatrix}, egin{pmatrix} t+1 \ t end{pmatrix}, dots),那么它对下一阶段同一段的贡献依然保持这一形式,不过(t)会增加(1)

    除了上一阶段同一段的贡献,上一阶段更小的段也会产生贡献:使当前段所有dp值加上一个常数,这可以被看成(t=0)的情况乘上一个常数。因此,一段的dp值可以被拆分为若干个(cegin{pmatrix} t \ t end{pmatrix}, cegin{pmatrix} t+1 \ t end{pmatrix}, dots)的和的形式,并且在转移中依然保持这个形式。其实也就是归纳证明了这个表示方法。

    这样一来其实已经做出来了,对每个阶段每个值域段存储一个(c-t) pair的列表即可。在转移时,直接把上一阶段同一值域段的列表复制过来,所有(t)(1),再增加一项更小的值域段的贡献。这样,列表的长度每过一个阶段至多增加(1),是(O(n))的。转移时从小到大枚举值域段,累加前一阶段贡献的同时算出这一阶段。这里要做的是把前一阶段当前值域段的dp值之和累加进去。一个(c-t) pair对应的和是一个组合数,经过(O(n^2))的预处理是可以(O(1))做的。因此对于(O(n))段,每段枚举(O(n))(c-t) pair,每阶段耗时(O(n^2))。同值域段转移时复制vector也是一样的复杂度,所以复杂度是(O(n^3))

    因为(n)很小,我比赛的时候并没有预处理组合数,复杂度实际是(O(n^4))的,依然跑得飞快。

  • 相关阅读:
    POJ 1469 COURSES 二分图最大匹配
    POJ 1325 Machine Schedule 二分图最大匹配
    USACO Humble Numbers DP?
    SGU 194 Reactor Cooling 带容量上下限制的网络流
    POJ 3084 Panic Room 求最小割
    ZOJ 2587 Unique Attack 判断最小割是否唯一
    Poj 1815 Friendship 枚举+求最小割
    POJ 3308 Paratroopers 最小点权覆盖 求最小割
    1227. Rally Championship
    Etaoin Shrdlu
  • 原文地址:https://www.cnblogs.com/lkmcfj/p/12248081.html
Copyright © 2011-2022 走看看