JOISC 2016

D1T1 マトリョーシカ人形

Description

\(n\) 个点,第 \(i\) 个点的 \((a_i, b_i)\),有 \(q\) 组询问,每组询问给定 \(A, B\),保留所有满足 \(a_i \ge A\)\(b_i \le B\) 的点,对于点 \((a_i, b_i)\)\((a_j, b_j)\),若 \(a_i \ge a_j\)\(b_i \ge b_j\) 则可以从 \(i\)\(j\) 连一条边。要求用若干条链覆盖整张图,使得任意两条链不交,求最小链数。

\(n \le 2 \times 10^5, a_i, b_i, A, B \le 10^9\)

Solution

可以证明一定存在一种最小链覆盖使得任意两条链不相交,所以根据 Dilworth 引理,我们知道这就等价于让我们求最长反链,而它又等价于求最长的序列,使得序列中的点 \(a\) 不降、\(b\) 不增。

发现这等价于让我们求最长不升子序列的长度。我们可以把所有点和询问按照横坐标从大到小排序,那么就变成了加点和查询值域 \(\le x\) 的 LDS 长度。

这个东西我们可以用线段树维护一下以每个数结尾的 LDS 长度,当然需要离散化。又发现一次操作为单点修改或查询前缀 \(\max\),所以可以直接把线段树改成树状数组。

需要注意的是原题中要求的是严格小于,那么反链中就不需要严格了,并且排序的时候也要注意横坐标相等时需要按照纵坐标从小到大排。

时间复杂度 \(\mathcal{O}(n \log n)\)


D1T3 ソリティア

Description

给定一个 \(3 \times n\) 的棋盘,其中一些格子上有棋子。问有多少种把棋盘填满的落子顺序,使得每个棋子落下时其左右两格都有棋子或上下两个都有棋子,答案对 \(10^9 + 7\) 取模。

\(n \le 2 \times 10^3\)

Solution

好像是之前的考试题?记不太清了。

我们来思考一下什么时候会有解。显然第 \(1\) 行和第 \(3\) 行可以放棋子当且仅当其左右都放了,所以这两行不能有连续两个没有放。特别地,四个角也必须放。除此以外大概就没有什么限制了。

不妨把第 \(2\) 行每一段极大的没有放棋子的段(即每个含有第二行格子的没放棋子格子的连通块)拿出来,那么棋子的放置情况一定形如这样:

oxxooxx
xxxxxxx
xoxxoxo

考虑 DP,这里仅讨论一个连通块的情况。排列计数常用的套路是考虑在原有的排列中加入新的数,从而实现 \(1 \to n\) 的递推。

在这里,我们设 \(f_{i, j, 0 / 1}\) 表示第 \(2\) 行第 \(i\) 列在 \(1 \sim i\) 列中第 \(j\) 个放置,并且是在其上下有棋子 / 上下不全有棋子但左右有棋子的情况下放置的方案数。

考虑转移。\(f_{i, j, 0}\) 的转移需要涉及到第 \(2\) 行第 \(i - 1\) 列的棋子是在哪种情况下转移的;而 \(f_{i, j, 1}\) 的转移必须要求 \(i - 1\) 在它前面放置,并且其上下格子中至少有一个在它后面放置。两个东西推一推就可以得到转移方程,比较恶心。

时间复杂度 \(\mathcal{O}(n^2)\),代码比较难写。


D2T1 雇用計画

Description

维护一个长度为 \(n\) 的序列 \(a\),支持两种操作:

  • \(a_x\) 修改为 \(y\)
  • 查询 \(a\) 中所有使得 \(a_i > x\)\(i\) 构成了几个连通块。

\(n, m \le 2 \times 10^5\)

Solution

\(s_i\) 为询问中 \(x = i\) 时的答案。发现一次操作等价于对 \(s\) 进行区间修改,直接树状数组即可,时间复杂度 \(\mathcal{O}(n \log n)\)


D2T3 トイレ

Description

\(2n\) 个人,其中一些是女装大佬。有两个服装发放点,其中一个发放男装,另一个发放女装。每个人恰好领取一套服装,领取一套服装需要一分钟,一个发放点每次只能给一个人发放服装。现在这 \(2n\) 个人排成一队领取服装。如果当前队首的人是普通男生,如果发放男装的地方空了他就领男装,否则如果发放女装的地方空了,他就会邀请当前排在最前面的女装大佬先去领取女装;如果当前队首的人是女装大佬,如果发放女装的位置空了他就会领取女装,否则如果发男装的位置空了他就会去领取男装。

现在需要在 \(n\) 分钟之内领完所有的服装,你可以重新排他们的顺序。定义一个人的不满度为重排之前在其后面但是重排之后到其前面的人的个数。求所有合法的重排方案中所有人不满度最大值的最小值。

\(n \le 10^{18}\),输入由多组字符串和数字给定,数字表示字符串重复的次数。

Solution

省选前集训期间考试题。

题目就是要求 \(2\) 个发放点必须一直发。考虑什么时候会出现卡壳的情况。首先普通男生是不会领女装的,所以如果女装大佬的个数 \(<n\),那就直接返回。否则,设女装大佬由 \(k \ge n\) 个,我们发现至多 \(k - n\) 个女装大佬要领男装。而女装大佬领男装的条件是轮到他前面的女生个数大于男生个数。所以我们把普通男生的权值设为 \(-1\),女装大佬的权值设为 \(1\),那就等价于没有前缀和大于 \(0\) 的情况。

可以贪心做。具体地,第 \(i\) 个男生必然在第 \(i\) 个女生前面,所以我们可以分别统计出他们的位置维护。如果 \(n \le 10^5\) 那将非常好做,不过 \(n \le 10^{18}\) 之后就变得有点恶心了,不过还不至于毒瘤。


D3T2 回転寿司

Description

\(n\) 个数 \(a_{1 \sim n}\) 顺时针排成一个圈,定义一次操作为给定 \(A, l, r\),从 \(l\) 顺时针枚举到 \(r\)(因此可能有 \(l > r\)),设当前枚举到了 \(i\),若 \(a_i > A\) 则交换二者。操作之间相互独立,输出每一次操作后 \(A\) 最终的值。

\(n \le 4 \times 10^5, m \le 2.5 \times 10^4\)

Solution

考虑分块。对于一个整块肯定是考虑块内的最大值,散块暴力即可。重构的话可以用一个小根堆记录每个块所有的修改,每次和堆顶比较、交换即可。

时间复杂度 \(\mathcal{O}(m \sqrt n \log n)\)

posted @ 2021-07-25 17:34  Scintilla06  阅读(113)  评论(0编辑  收藏  举报