GMOJ 2020.10.29【NOIP提高A组】模拟

GMOJ 2020.10.29【NOIP提高A组】模拟

一套前三题较为简单但是并没有做出来的膜你赛

T1.6806achen

首先, \(A\), \(B\) 是可以对调的, 所以默认 \(A < B\)

可以发现, 如果 \(A\) 左边有大于2个点, 那么走完 \(A\) 左边方案唯一, 且最后停在 \(A + 1\), 对于\(B\) 同理.

所以方案数就为 \(A + 1\)\(B - 1\) 的方案数.

\(f[i]\) 为从1到 \(i\) 的方案数, 显然 \(f[i] = f[i - 3] + f[i - 1]\).

还有一点特殊情况也十分好判.


T2.6808tree

首先假定根为\(1\), 答案可以分为两部分讨论 :

1.以\(u\)为根的子树中包含所有颜色, 那么 \(u\) 对答案的贡献为 \(u\)子树以外到 \(u\) 的最长链

2.以\(u\)为根的子树中没有完全包含任何颜色, 那么 \(u\) 对答案的贡献为 \(u\) 到 叶子节点的最长链

每个点的贡献是十分好算的, 问题在于如何判断这个点是否能贡献.

对于 1, 可以按 \(dfs\)序遍历所有点, 每个点到根的路径加1, 它与前一个颜色相同的点的 \(lca\) 到根的路径减1. 其实就是一次树上差分, 最后有1贡献的充要条件是点的和为 \(m\).

对于2, 只分别需要求出每种颜色的点的 \(lca\), 显然 \(lca\) 到根路径上的点完全包含这种颜色, 在 \(lca\) 打标记, 最后上传标记即可.

只要倍增\(lca\) 的常数够优秀, 也是能过这道题的.


T3.6808east

先讨论 \(a_i\) 各不相同的情况,显然一个区间 \([l, r]\) 满足要求的充要条件为 \(max(a_i) - min(a_i) = r - l\), \((l \leq i \leq r)\)

又可以发现 \(max - min \geq r - l\), 移项得 \(max - min + l \geq r\),所以对于每个右端点 \(r\),需要维护 \(max - nin + l\) 的最小值以及取到最小值的左端点数。

考虑用两个单调栈分别维护 \(max\)\(min\)。对于 \(max\),维护一个单调递减的单调栈,每次弹栈的时候,需要修改一个区间的 \(max\),发现这段区间的 \(max\) 相同,所以其实就是一个区间加操作,维护 \(min\) 同理,所以用一棵线段树维护即可。

再考虑有 \(a_i\) 相同的情况,可以发现上面式子变为 \(max - min + l + cnt \geq r\)\(cnt\) 为区间内不是第一次出现的数的个数,记录 \(a_i\) 上一次出现的位置 \(las[a_i]\),那么其实就是一个区间加1的操作,同样线段树上搞一搞就好。


T4.6809不难题

Description

给定 k 行 n 列的矩阵,每行为 \(1\) ~ \(n\) 的排列,互相独立且随机。

要求将一个区间 \([L, R]\) 的行拉出来合成一行,不能有连续的 \(R - L + 1\) 个数相同,

求所有区间的方案数之和

Solution

乍一看感觉挺难求的,再一看还是很难求.....

先在每一行末尾加 \(n + 1\),那么区间 \([L, R]\) 满足条件的方案数就转化为 第一次连续出现 \(R - L + 1\) 次的数为 \(n + 1\) 的方案数 / \((R - L + 1)!\)

转化之后便比较好设状态了,设 \(f[x]\) 表示区间 \([L, R]\) 中第一次连续出现 \(R - L + 1\) 次的数为 \(x\) 的方案数,考虑用 “总方案数” - “不合法方案数”,总方案数就是一堆组合数的乘积。

考虑如何求 \(f[x]\),如果不需要 \(x\) 为第一次连续出现的话,\(f[x] =\) 将每行 \(x\) 之前的数乱排乘 \((R - L + 1)!\),但需要删去 \(x\) 不是第一个连续出现的情况,设 \(y\) 表示第一次连续出现 \(R - L + 1\) 次的数为 y,且要求 \(x\) 能在 \(y\) 连续出现 \(R - L + 1\) 次后连续出现,也就是 \([L, R]\)\(x\) 的位置都要在 \(y\) 之后,那么对于每个 \(y\),就是 \(f[y] \times\) 一堆组合数的积,积表示 \(y\)连续到 \(x\)连续之间有多少种不同的排列方案。

固定区间左端点,枚举右端点店铺dp,时间复杂度 \(O(k^2n^2)\),并过不了,但是注意到题目中每一行的排列独立且随机。也就是说,对于满足条件的 \((x, y)\),在只有一行时数量为 \(\frac{n^2}2\),以后每多一行,依然满足条件的概率为 \(\frac12\),所以数量也相应的\(/2\),所以对于一次左端点固定,右端点移动的过程中,\((x, y)\)的总数是\(O(n^2)\)的。

综上,在每次新加入一行时维护合法 \((x, y)\),可以使用链表维护,时间复杂度 \(O(nk(n + k))\)

最后答案为 \(\frac{f[n + 1]}{(R - L + 1)!}\)

posted @ 2020-11-01 11:53  buzzhou  阅读(113)  评论(0编辑  收藏  举报