C
感觉还是不熟练与拆位相关的题目,补了半天才补出来。
问某个区间内符合某种性质的数的个数,很容易想到用前缀和思想转化,则问题转化为快速求出在\([1,x]\)中高位比其余位上数字都大的数字的个数。
设\(x\)共\(num\)位,最高位数字为\(d1\)。
可以分为\(4\)种情况考虑,每种情况都只需要注意两点:
- 考虑的数字要\(<=x\)
- 任意\(2<=i<=num\),\(d_1>d_i\)
具体见官方题解:editoral
code
F
缩点 + 拓扑\(dp\)
题目条件相当于给定 \(n\) 对\((b_i,b_j)\)的偏序关系\((1<=i,j<=n)\),且\(1<=b_i<=m\),求符合条件的\(b\)数组的方案数。
可以想到建图跑拓扑\(dp\)。对于建图后的环,环中的每个数一定都是相同的,因此可以缩成一个点。这样缩点后的图为\(DAG\),可以直接在其上跑拓扑\(dp\)。
设置状态:\(dp[i][j]\):结点\(i\)上数字为\(j\)时的方案数
\(ans\):
\[\prod_{u}^{u的出度为0}(\sum_{j=1}^{m}dp[u][j])
\]
\(init\):无边的限制时,所有状态均合法,方案数均为\(1\)。
\(trans\):
\[dp[v][j] = \prod_{u}^{u->v}(\sum_{i=1}^{j}dp[u][i])
\]
其中可设置 \(dp\) 的前缀和数组 \(dps\) 来优化求和过程,具体细节见代码。
code