2025.6.10 NOI 模拟赛 题解

比赛

T1 NFLS #P10190. 玩游戏 \(\quad\) Baekjoon-16749 Sixth Sense

题意

给定 \(b_{1\sim n}\)\(a_{1\sim n}\),重排 \(a_{1\sim n}\) 使得 \(\sum_i [a_i>b_i]\) 最大的情况下 \(a\) 字典序最大,求出合法解,\(n,a_i,b_i\le10^5\)

分析

\(a_i\) 视为左括号,\(b_i\) 视为右括号,按值从大到小排序,若相同则视为 \(b\) 更大

根据排序后的下标把 \(a_{1\sim n}\) 离散化为 \(A_{1\sim n}\)\(b_{1\sim n}\) 离散化为 \(B_{1\sim n}\)

一个括号序列合法的条件为左括号看为 \(+1\) 右括号看为 \(-1\) 后总和 \(=0\) 且任意前缀和 \(\ge 0\)

题目要选择 \(a\)\(b\) 的一个最大的子集使得其匹配,一种最优策略为从小到大对于每个右括号找到最大的可以匹配且还没有匹配的左括号匹配

先预处理出一种合法的匹配,此时匹配的一定为 \(b\) 从小到大排序后的一个前缀

若选择 \(a_i\) 则位置 \(A_i\) 处值为 \(1\),若选择 \(b_i\) 则位置 \(B_i\) 处值为 \(-1\),若不选择则对应位置值为 \(0\),用线段树维护其前缀和

线段树中先加入所有 \(a_i\) 和已经匹配的 \(b_i\),每次若匹配一对 \(a_i\)\(b_i\) 则从中删去,若当前剩余的 \(b_i\) 可以匹配 \(a_i\) 则线段树全局最小值 \(\ge 0\),否则不能匹配

考虑字典序需要最大,因此从左往右扫描,贪心令当前位最大

显然当前位置匹配字典序一定大于当前位置不匹配,因此优先考虑匹配

用一个集合保存已经匹配的 \(b_i\)(排序方式同 \(B\)

若当前 \(b_i\) 已经匹配,则当前位置匹配

否则若存在已经匹配的 \(b_i\),则取出最小的(即线段树中最靠左的),线段树中删去这一位置,加入当前位置,若操作后仍然可以匹配(最小值 \(\ge 0\)),则说明当前位置可以匹配,删去原先的匹配,否则还原

若当前位置可以匹配,尝试找到可以和它匹配的最大左括号,相当于找到最大的位置使得对应所有后缀和都 \(>0\),容易线段树上二分求出

若无法匹配,则找到最大的可以删去之且剩余仍然可以匹配的位置,发现同上

总时间复杂度 \(O(n\log n)\)

代码

参考

T2 NFLS #P12935. Permutation

题意

对于 \(a_{1\sim n}\),排列 \(p\) 合法当且仅当对于矩阵 \(M_{i,j}=[p_i=j]\) 中每个位置 \((i,j)\),不存在一个包含 \((i,j)\)\((a_j+1)\times(a_j+1)\) 的子矩阵满足该子矩阵只有主对角线为 \(1\) 或只有副对角线为 \(1\),求合法排列数量,\(n\le500\)

分析

翻转矩阵,则排列合法当且仅当 \(i\) 所在极长上升、下降(等差数列且公差为 \(+1/-1\))子段的长度不超过 \(a_i\)

称极长上升、下降子段为区间,若干区间的并为段

\(f_{i,j,k}\) 表示把 \(1\sim i\) 划分为 \(j\) 段(值域上的连续段),最后一个区间的最后一个位置与 \(k\) 个边缘(值域上的连续段左右两侧的位置,若段长度为 \(1\) 则算两次)重合,该情况下的方案数

边界情况为 \(f_{0,0,0}=1\),表示没有连续段的情况,答案为 \(\sum_k f_{n,1,k}\)

显然区间 \([l,r]\) 合法当且仅当 \(r-l+1\le \min_{i=l}^r a_i\),具有单调性,对于每个右端点 \(r\) 求出最小的合法左端点 \(lp_r\)

考虑 \(f_{i,j,k}\) 的转移

\([i,i]\) 作为一个区间(显然其一定合法):

  • 新增一段:\(f_{i-1,j-1,k}\to f_{i,j,2}\)
  • 拼在某一段边上:\((2j-k)f_{i-1,j,k}\to f_{i,j,1}\)(减去 \(k\) 是因为不能相邻,否则会与之前一段合并,从而不是极大的)
  • 连接两段:\((j+1-[k\ge 1])(j-[k\ge 2])f_{i-1,j+1,k}\to f_{i,j,0}\)

若区间长度 \(>1\),设为 \(w\),令 \(x=i-w\),即 \([x+1,i]\) 作为一个区间:

  • 新增一段:\(2f_{x,j-1,k}\to f_{i,j,2}\)
  • 拼接(当前区间第一个数在值域上朝向所拼接的区间):\((2j-k)f_{x,j,k}\to f_{i,j,1}\)
  • 拼接(朝向另一侧):\(2jf_{x,j,k}\to f_{i,j,0}\)
  • 拼接:\((j^2k+j(j+1)(2-k))f_{x,j+1,k}\to f_{i,j,0}\)

容易前缀和优化到 \(O(n^2)\)

代码

参考

T3 NFLS #P13091. 棋盘 \(\quad\) AT_codefestival_2016_final_j Neue Spiel

题意

一个 \(n\times n\) 的网格,每个格子上可以存在至多一个物体,定义操作 \((\text L,i)\) 表示从第 \(i\) 行第一列左侧的位置插入一个物体(这个物体以右的会依次移动一格),操作 \((\text R,i)\)\((\text U,i)\)\((\text D,i)\) 同理,给定 \(4n\) 种操作的数量(总和为 \(n\times n\)),要求构造出这些操作的一个排列,使得从空网格开始依次执行操作,可以令 \(n\times n\) 个格子上恰好都有一个物体,\(n\le300\)

分析

把插入操作转化为在那一方向上第一个空位处放置一个物体

考虑求出每个物体是由哪个操作放置的,\(4n\) 个操作作为左部点,\(n^2\) 个位置作为右部点,左部点匹配次数为操作的数量,右部点匹配一次,每个左部点向对应的 \(n\) 个右部点(在对应行或对应列)连边,网络流求出一组完美匹配,若不存在则无解,这部分时间复杂度为 \(O(n^2\sqrt{n^2})=O(n^3)\)

\(P(x,y)\) 为放置 \((x,y)\) 处的物品的操作的种类(\(\text {LRUD}\) 之一)

考虑如何排列操作,若 \(P(x,y)=\text L\)\((x,y)\) 左侧的物体都需要在 \((x,y)\) 之前放置,连边 \((x,y)\to (x,u<y)\),其他方向同理

若依赖关系为 \(\text{DAG}\) 则根据拓扑序操作即可,否则需要调整环上的 \(P(x,y)\)

发现对于一个环,将环上所有位置的操作按环的方向整体旋转一次,即可消除这个环,且仍然满足匹配

可证若每次找到一个环就消除之,则总消除的环长为 \(O(n^3)\) 的,因此若能在 \(O(L)\) 内找到一个长为 \(L\) 的环,即可 \(O(n^3)\) 调整整张图

\(\text{dfs}\) 时特殊处理即可

总时间复杂度 \(O(n^3)\)

代码

参考

比赛结果

\(60+10+26\)\(\text{rk}55\)

posted @ 2025-06-12 07:30  Hstry  阅读(99)  评论(0)    收藏  举报