做题记录 25.3.24

\(\textcolor{green}\odot\) CF1970F3 Playing Quidditch (Hard)

模拟即可

代码

\(\textcolor{purple}\odot\) CF1970D2 Arithmancy (Medium)

直接随机,随机时固定 \(\text O\)\(\text X\) 的比例为 \(1:10\) 左右,大约随 \(5\) 次就可以出结果

代码

参考

\(\textcolor{blue}\odot\) CF1970B3 Exact Neighbours (Hard)

对于存在 \(a_i=0\) 的情况,选择一个 \(a_i=0\)\(i\) 放到 \((1,1)\),其他 \(=0\) 的放到最后,将 \(a_i\ne 0\) 的从大到小排序,然后之字形从 \((1,1)\) 开始填充

对于 \(a_i\ne 0\)\(a_i\) 中存在重复的情况,设 \(a_i=a_j=v\),则将 \(i\) 放在 \((1,v)\)\(j\) 放在 \((2,1)\),剩余从大到小排序,之字形从 \((2,1)\) 开始填充

剩余情况 \(a_i\) 为一个排列,\(n=2\) 时无解,其他情况下将 \(a_i=1\) 的放在 \((1,2)\)\(=2\) 的放在 \((2,2)\)\(=3\) 的放在 \((3,1)\),剩余从大到小从 \((3,1)\) 开始填充

时间复杂度 \(O(n\log n)\),可优化到 \(O(n)\)

代码

参考

\(\textcolor{blue}\odot\) CF1970A3 Balanced Unshuffle (Hard)

对于原序列中一对相匹配的括号,右括号的 \(w\) 为左括号的 \(w\) 加一,因此 \(w=k\) 的左括号数量等于 \(w=k+1\) 的右括号数量

维护栈 \(s_{0\sim n}\)\(s_i\) 中保存 \(w=i\) 的位置的字符,栈顶对应字符在原序列的左侧,变换后序列的右侧(\(w\) 相同的变换后逆序)

变换后的序列中从左到右 \(w\) 不降,令 \(w\) 相同的为一段,令 \(x\gets 0\) 表示当前处理位置的 \(w\),记录一个值 \(l\) 表示当前位置所在中左括号数量,初始为 \(0\),然后扫描原序列

设当前扫到 \(i\) 位置

\(c_i\) 为左括号则直接加入 \(s_x\) 并令 \(l\) 加一

\(c_i\) 为右括号,由于第 \(x\) 段中右括号数量是确定的(等于第 \(x-1\) 段的左括号数量),因此 \(c_i\) 不能加入第 \(x\) 段,因此令 \(x\gets x+1\),令 \(u\gets l,l\gets 0\),然后继续向后扫描,将扫到的字符加入 \(s_x\),若扫到左括号则 \(l\) 加一,否则 \(u\) 减一,\(u=0\) 时跳出

输出时,从 \(s_0\) 开始,每次取出最后一个字符输出,若为左括号则栈下标加一,否则减一

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

代码

参考

\(\textcolor{blue}\odot\) CF1969E Unique Array

相当于询问至少在序列上删掉多少位置,使得剩下每个连续段都合法

对于 \(a_i\),令上一个与之相同的位置为 \(pr_i\),下一个为 \(nx_i\),则所有区间 \((l,r)\mid l\in(pr_i,i],r\in[i,nx_i)\) 都合法

扫描序列,若最后一段不再合法则新分割出一段,转化为每次给定右端点,查询给定区间内的左端点是否合法

对右端点扫描线,则转化为区间加减,区间判断是否有 \(0\),线段树即可

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

代码

参考

\(\textcolor{blue}\odot\) P10494 [USACO02FEB] Power Hungry Cows

迭代加深搜索模板,注意简单剪枝

代码

参考

posted @ 2025-03-25 07:20  Hstry  阅读(6)  评论(0)    收藏  举报