NOIP训练赛#14

时间安排

8:05~8:53 写完T1+跑样例,但是做法假了(居然还能过大样例)

8:55~10:53 写完T2 T3的暴力(状态不好,暴力调了很久)

10:55~11:25 打表找 T3规律并想正解

11:30~11:50 写完T4暴力,但发现时间复杂度假了

题解

T1

先跑 \(n\)\(dijkstra\) 求出两两最短路,对于点对 \(i,j\) 而言,若 \(dis_{i,j}\leq t_i\) ,则连一条权值为 \(c_i\) 的边,最后跑一遍 \(dijkstra\)

T2

考虑将原问题转化为在一个 \(n\times m\) 的矩阵中放置 \(n\times 2\)\(1\) ,使得对于第 \(i\) , \([1,l_i]\) 列和 \([r_i,m]\) 列中各放一个 \(1\) 的方案数 (重点计数技巧)

考虑设 \(dp_{i,j,k}\) 表示已经考虑了前 \(i\) 列,当前前 \(i\) 列中有 \(j\) 个右区间还没有被满足,还有 \(k\) 列没有选 \(1\) 的方案数 ,可以发现 \(k\) 可以由 \(i,j\) 转移出来,故省掉一维

首先考虑对于 \(l,r\) 均做前缀和,那么 \(suml_i\) 表示在 \(i\) 之前截止的左区间的个数, \(sumr_i\) 表示在 \(i\) 之前开始的右区间

考虑枚举顺序先列后行

\(l\) 表示当前列至少满足截止时间为 \(i\) 的左区间的个数, \(r\) 表示还需要满足多少个右区间, \(nowr\) 表示当前这一列中有多少个右区间需要满足

则可以计算出 \(k=i+1-r-suml_i\) (当前剩余的可以供选择的列数)

\(j+nowr \ge 1\)\(k \ge l+1\) (有需要填的右区间且剩余列数大于1)时

\(dp_{i+1,j+nowr-1}+=dp_{i,j}\times C_{nowr+j}^1\times A_{k-1}^l\) (从 \(l+1\) 个剩余位置中选择 \(l\) 个位置放 左区间(由于是截止,所以必须放),再选择一个放 \(nowr+j\) 中的任意一个右区间的方案数转移到 \(i+1\) 列,\(j+nowr-1\) 个空位的情况)

\(k \ge l\) 时,考虑只填左区间的情况

\(dp_{i+1,j+nowr}+=dp[i][j]\times A_k^l\)

一句话就是在当前行中,减去必须选去的列数,剩下的空列排列计数即可

初始化 \(dp_{0,0}=1\) ,答案为 \(dp_{m,0}\)

T3

引理 :区间 \((1,x)\) 包含的二进制下有奇数个 \(1\) 的数字个数为 \(\frac x2+(x\%2||popcount(x)%2)\)

直接动态开点线段树维护区间中有奇数个 \(1\) 的数字的个数 \(odd\) 和区间中有偶数个 \(1\) 的数字的个数 \(even\) 即可

答案为 \(T[1].odd\times T[1].even\)

T4

设一个人最终占据了 \(x\) 个点,则方案数为 \(C_n^x\)

则选择某个固定点对的概率为 \(C_{n-2}^{x-2}=x(x-1)/(n(n-1))\)

则只需要计算有多少个点对距离为 \(dis\) 集合中的数,点分治即可

posted @ 2023-09-25 08:35  dubnium  阅读(35)  评论(0)    收藏  举报