首页 > 其他分享 >2024.10 做题笔记

2024.10 做题笔记

时间:2024-10-31 23:01:51浏览次数:6  
标签:2024.10 log 复杂度 矩阵 笔记 Cat 维护 Mouse

2024.10 做题笔记

10.2

随机化和搜索题还是太神秘

P9257 [PA 2022] Mędrcy

将每条咒语代表的不知道它的两个人连边,如果存在一个人不知道任何咒语,即图是菊花图,则第一天他就会离开

否则第二天相当于每个人知道了每个人都至少知道一条咒语,那么如果一个人发现自己知道的咒语中有人一条都不知道,就说明那个人知道自己不知道的咒语,则他就会离开,去掉这个人相邻的边后,图是菊花图

归纳地考虑,第 \(k\) 天相当于每个人都至少知道 \(k-1\) 条咒语,将问题转化为求图中的最小点覆盖,如果大小 \(\le x\) 则输出所有可能在最小点覆盖中的点

求任意图的最小点覆盖显然是不可做问题,只能搜索

环和链都能直接计算,如果想优化搜索的复杂度则每次找度数最大的点 \(x\),此时 \(deg_x\ge 3\),枚举 \(x\) 是否在最小点覆盖中,如果在则去掉 \(x\) 及其相邻的边,否则相邻边的另一端点必须在最小点覆盖中

这部分的复杂度写出递推式,最坏情况下不选 \(x\) 能确定 \(3\) 个点,\(T(k)=T(k-1)+T(k-3)+O(n)\),由于最多只会选 \(30\) 个点,复杂度暴力算出来大概是 \(O(1.4656^k)\)

复杂度咋算的?把后面看成 \(O(1)\),解特征方程 \(x^3=x^2+1\),得到两个根 \(A,B\),递推式大概是 \(aA^k+bB^k\),取较大根是 \(1.4656\)

P4581 [BJOI2014] 想法

把组成新题目的两个题目向新题目连边,得到了 DAG,要粗略求每个点前驱中 \(1\sim m\) 的点数

点数太多了无法使用 bitset,考虑近似算法

需要知道一个前置结论,如果在值域 \([0,v]\) 上等概率均匀随机取 \(n\) 个数,则最小值的期望为 \(\dfrac{v}{n+1}\)

反过来,如果知道某些这样得到的数的最小值,能求出数的期望个数

那么将 \(1\sim m\) 中的每个点赋予这样的随机权值,对剩下点拓扑排序求出前驱中的最小权值,求出期望个数,多做几次取平均值,实测做了 \(200\) 次可以

P7450 [THUSCH2017] 巧克力

中位数最小则二分答案 \(x\),\(\le x\) 的看作 \(-1\),\(>x\) 的看成 \(1\),要求选出的连通块权值非负

\(k\) 很小,随机将每种染上 \([1,k]\) 中任意一种颜色,要求选的颜色不同,正确率为 \(O(\dfrac{k!}{k^k})\)

然后就可以跑最小斯坦纳树,求最小权值即可,实测每次二分随机 \(T=150\) 次可以,复杂度 \(O(Tnm3^k\log V)\)

#3400. 「2020-2021 集训队作业」Storm

显然选出的街道集合不会成环,一定组成二分图,且最多涉及 \(k+1\) 个点

如果原图是二分图,可以建立费用流模型,\(S'\) 连左部点,右部点连 \(T\),每个点由于只能贡献一次,连流量为 \(1\),费用为点权和流量为 \(\infty\),费用为 \(0\) 的边,左部点和右部点的连边,流量为 \(1\),费用为负边权,\(S\) 连 \(S'\),流量为 \(K\),费用为 \(0\),跑最大费用可行流

如果原图不是二分图,把所有点随机染成黑白两种颜色,忽略同色点之间的边,这样染色正确的概率为 \(\dfrac 2{2^{k+1}}=\dfrac 1{2^k}\),随机跑 \(T2^k\) 次费用流即可,\(T=10\) 可以通过

费用流的复杂度 精细分析 可以得到为 \(O(k^2(n+m))\),大概是因为每次 spfa 每个点入队次数为 \(O(k)\) 次

「NOI2022模拟赛czx1」链式进化

怎么 acc 上模拟赛还有这个题……居然题解还给了确定性做法

\(O(n^2\log n)\) 就是对每行单独二分答案做,二分答案后双指针统计区间数即可

优化掉这只 $\log $ 的方法第一种就是随机打乱所有行,因为随机排列的前缀最大值个数期望为 \(O(\log n)\),每次只需要先 \(O(n)\) 判断这行比前一行大时的答案是否可行,如果可行再二分,期望复杂度 \(O(n^2+n\log^2n)\)

但这也给我们启发,我们不需要随机化的性质,由于 \(\operatorname{mex}\) 值域为 \(O(n)\),因此我们直接把行按 \(w\) 从大到小排序,则后面的行取到的答案必须增加,维护当前取到的答案是多少即可,如果符合就不断将答案 \(+1\) 并判断,复杂度是确定的 \(O(n^2)\)

Warrior

答案显然具有可二分性,关键是我们无法知道字典序刚好为 \(mid\) 的子段是谁,也无法比较它和其它子段的字典序

于是我们随机一个子段作为基准,枚举其它子段开头为 \(l\),则如果 \([l,r]\) 比它字典序小则 \([l,r'](r'>r)\) 也比它字典序小,同理 \([l',r](l'<l)\) 也比它字典序小

双指针维护 \(l,r\),维护线段树表示区间内每种数的个数,每次移动即可线段树上二分

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

但随机的 \(\log\) 常数较大,据说能被卡(

10.3

D. 小D与圣诞树

一开始没看到初始所有颜色不同,发现不会打暴力,由于只有修改到根链上的颜色为新颜色,因此每种颜色的点能组成一条路径

考虑点 \(u\) 到根链上的颜色数 \(f_u\),即考虑多少个点与父节点颜色不同,这样路径查询也可以变成 \(f_u+f_v-f_{lca}\times 2+1\)

路径修改考虑树链剖分,在每条重链上相当于区间推平,可以用 set 维护连续段

查询子树中 \(f\) 的最大值,可以在维护连续段的过程中,用线段树维护 dfs 序一段区间 \(f\) 的最大值,要支持区间加减,区间查询,每次修改颜色时,先去掉原来的段的交界处对子树 \(f\) 的贡献,再加上新的

根据颜色段均摊,总共只会增加 \(O(q\log n)\) 段,复杂度为 \(O(q\log ^2 n)\)

10.6

A. CF1503E 2-Coloring

这种题肯定考虑刻画合法方案的形态,发现蓝色格子是上下两个单峰形状,有两种情况,一种是两个峰不挨着,另一种是上面峰的最左端紧靠着下面峰的最右端,或反过来上面的最右端靠着下面的最左端

第一种情况,上下独立,直接分别枚举上下中最大值最靠右的,最靠左的,不挨着就行,不是峰的位置就形如不降子序列的计数,最后前缀和优化一下

第二种情况同理,直接枚举交界的格子,用组合数算方案

注意对称性,两边如果只枚举上最靠右下最靠左记得乘二

赛时怎么只记得把第二种情况 \(\times2\) 啊,还死活看不出来啊

D. 棋盘

赛时看到矩阵乘法优化,直接一眼鉴定为转置原理,然后不会求逆,最后发现由于它的变换不是形如「某一行全部加到下一行」这种有先后顺序的操作,可以看作把矩阵复制一遍,再杂乱地执行很多次把原矩阵的一行加到新矩阵的某行这样的操作,无法用转置原理去求逆

好像有人告诉我本质原因是转移矩阵不是初等矩阵?不知道啊(

不过分析询问的性质,可以看作是先预处理处整个棋盘,询问的区间左端点,右端点均不降

转移矩阵中只有 \(O(n)\) 个非零元素,可以 \(O(n^2)\) 完成一次乘法

每次弹出左端点,如果维护了后缀信息就能直接做,加入右端点,维护了前缀信息就好了

于是用两个栈,左边栈维护从栈底位置开始的后缀信息,右边维护从栈底开始的前缀信息

唯一的问题是如果左边栈空了,就无法继续弹出

那暴力把所有元素放到左边,发现这样每个元素最多被重构一次,复杂度均摊还是 \(O(qn^2)\)

我只不过多存了一行的信息,导致转移矩阵大小 \(\times 4\) 既被卡时间又被卡空间,后来发现这种做法只需要把前一个、前两个转移矩阵都乘一下,代表从前一行、前两行转移,加起来就好了,分界点处维护相邻两种分界点……

10.21

B. P10093 [ROIR 2022 Day 2] 礼物

枚举第 \(k\) 大的数是多少,把 \(\ge\) 它的数看成 \(1\),则区间内包含 \(k\) 个 \(1\)

从大到小加入数,每加入一个数就处理包含它的区间

那么每次只需处理 \(O(k)\) 个区间,然后用 ST 表维护区间最值,链表维护每个数的前面、后面一个已经加入的数

复杂度 \(O(nk+n\log n)\)

D. QOJ 6473 Cat and Mouse

直观的理解是 Cat 开始在 \(1\) 号点,Mouse 开始在 \(x\),Mouse 先移动,要操作 Cat 的移动,在尽可能少的步数内使得 Mouse 无路可走

可以朴素设计 \(f_{x,y}\) 表示 Mouse 在 \(x\),Cat 在 \(y\) 时最少移动步数,加上转移均摊复杂度为 \(O(n^2)\),据说设计 A* 跑 BFS 可以通过?

发现 Cat 不在 Mouse 的相邻点或不是它下一步走的点时,它根本不会影响 Mouse 的移动,而且此时 Mouse 不会自己停止,设状态二元组为 \((x,u)\),所以只有 \(F(x,x)=u\) 时是关键的,注意状态中 Mouse 即 \(x\) 先走,初始为 \((X,1)\)

这之后 Cat 一直会贴在 Mouse 的旁边,否则重新让 Mouse 自由移动不优,就有两种情况:

  • Cat 在 \(u\),一直跟着 Mouse 移动,\((x,u)\to (F(x,u),x)\)
  • \(u\) 在 \(x\) 的移动方向上,使 \(x\) 转向,Mouse 移动至 \(w=F(x,u)\),目标状态为 \((x,w)\)

剩下的问题是构造一种步数最少的方法,首先存在方案的条件是 \(F(w,w)=x\),否则 Cat 追不上 Mouse,Cat 先在 \(u\) 不动,下一步 Mouse 到了 \(F(w,u)=x\),Cat 再到 \(x\),到达状态 \((x,x)\)

分类讨论 \(F(x,x)\) 的取值,根据上面的情况它只有两种可能:

  • \(F(x,x)=w\),此时最优情况下 Cat 移动到 \(w\),到达 \((w,w)\),然后不动即可到 \((x,w)\),加上前面共花费 \(4\) 步
  • \(F(x,x)=u\),会到达 \((u,x)\),但 Mouse 本来就是从 \(u\) 走过来的,让它返回不如早拦截,且若 \(u\) 不是第一格可以实现在早一格拦截,否则直接换一种相邻状态更优,舍去

于是把关键状态之间连边,跑最短路,点数和边数都是 \(O(n)\) 的,可以直接做也可以用桶维护最短路长度

最后枚举走了 \(i\) 步第一次到达关键状态,由于之前 Mouse 的移动不受限制,可以确定它的位置 \(p\),枚举邻居即 Cat 的位置 \(q\),此时若 \(q\)

为 \(p\) 的父节点则 \(dep_q-1\) 步走到即可,否则为了保持和 Mouse 之前错开,需要 \(dep_q\) 步

好像朴素枚举邻居虽然跑的很快但复杂度有点问题,不过这里应该就能随便优化了(

总复杂度为 \(O(n)/O(n\log n)\)

10.22

C. 歌剧演员

首先设计 DP,观察如果固定了某个空隙中的 LIS 对答案的贡献是哪一段,即要接在它前后哪两个数中间,则空隙中尽量使这段 LIS 最长最优

而且如果确定每个空隙的贡献,则它们产生贡献的值域不交,可以统计贡献

设第 \(i\) 个数前面有 \(a_i\) 个空隙,值 \(\le i\) 的有 \(s_i\) 个没确定位置,\(f_i\) 为序列第 \(i\) 个确定的数是 LIS 末尾时 LIS 最长长度

\[f_i=\max_{j<i,p_j<p_i}f_j+ \min(a_i-a_j,s_{p_i}-s_{p_j}) \]

拆开 \(\min\),即强行钦定一个更小,则转移是三维偏序,用 CDQ 分治优化即可

10.23

啥逆天 4h 场三个 DS 一个神秘数数……

B. P7172 [COCI2020-2021#3] Specijacija

我赛时想出了大力 \(O(n\log^2n)\) 维护法,就是关注每个点在第 \(i\) 层是从左往右第 \(x\) 个,每个 \(a_i\) 相当于一次操作,若 \(x>a_i\) 则 \(x\gets x - 1\)

显然一次操作代表的变换是个只有两段的分段函数,\(n\) 个操作是有 \(O(n)\) 段的分段函数,大力使用线段树维护区间 \([l,r]\) 内的操作复合后得到的分段函数

每个节点只用存储哪些点处后面的函数值要 \(-1\),相当于差分,建树时再用一棵线段树维护函数每个位置的取值,要线段树上二分找到第一个 \(>a_i\) 的位置,之后后缀减 \(1\),处理完后撤销操作就避免了重新建树

查询时二分找出前面有多少个 \(-1\) 处即可得到经过区间内操作后的值

先查询一次,将 \(x,y\) 拉至同一层,然后在维护操作的线段树上二分,找到 \(x,y\) 经过变换后第一次相同的位置即是 lca

赛时最后的线段树二分没及时剪枝变成 \(O(n\log^3n)\) 了,赛后改对了,LG 上喜提最劣解(

官解是注意到分岔点只有 \(O(n)\) 个,只需要求出叶子构成的虚树的树,把每个点放到对应的链上,求对应点的 lca

从下往上可以维护出每层每个点所属的链底部节点,每层相当于下一层只做了删除一个数,修改一个数,还要支持查询第 \(a_i\) 个,由于强制在线使用主席树维护,注意特判两个点在同一条链上的情况,lca 是深度更浅的点,复杂度 \(O(n\log n)\)

D. QOJ5020 举办乘凉州喵,举办乘凉州谢谢喵

先考虑 \(y\) 为 \(x\) 祖先的情况,这种去掉一个子节点的计数一般先考虑重链剖分,设 \(g(x,d)\) 为 \(x\) 除重儿子子树外 \(x\) 子树内距离 \(x\) 为 \(d\) 点的数量,\(f(x,d)\) 为 \(x\) 子树内距离 \(x\) 为 \(d\) 点的数量

那么答案是路径上点的 \(g(\star,d)\) 之和,再特殊处理路径上轻重链切换处的答案,是新重链底部的点 \(u\) 的 \(g(u,x)\) 加上它重儿子的 \(f(son(u),d-1)\) 减去路径上前一个点即上一条重链的链头 \(v\) 的 \(f(v,d-1)\)

子树外的贡献则是对 \(y\) 做邻域数点,去掉 \(f(y,d)\) 即可,邻域数点使用点分治,维护每种深度点数量的前缀和即可 \(O(n\log n)\)

考虑计算 \(f(\star,d)\),显然询问有 \(O(q\log n)\) 次,离线到每个点上使用启发式合并容易做到 \(O(n\log^2n)\),但这里的信息与深度有关,考虑长链剖分,维护每种深度点数量的后缀和,就能方便地完成在长链前端增加一个数和查询的操作,复杂度瓶颈为查询,\(O(q\log n)\)

最后则是一条路径上 \(g\) 的和,由于所有节点轻子树大小为 \(O(n\log n)\),将询问拆成两条到根的路径相减,dfs 的过程中直接暴力加入当前点轻子树,回溯时撤销就得到了到根路径上 \(g\) 之和,复杂度 \(O(n\log n)\)

于是整道题复杂度 \(O((n+q)\log n)\)

10.24

C. 换猫

首先我不知道需要知道结论,如果按顺序依次给每种字符交替赋值为矩阵 \(A_c,A_c^{-1}\),则区间合法的充要条件是区间矩阵乘积为 \(I\)​

给每种字符随机一个可逆矩阵即可,这里取 \(2\times 2\) 正确率就足够了

每次交换的两个位置 \(l,r\) 会导致 \(l,r\) 处矩阵产生改变,\([l+1,r-1]\) 内矩阵变为原来的逆矩阵

设矩阵前缀积为 \(pre_i\),后缀积为 \(suf_i\),将矩阵变成原来的逆矩阵后的前缀积是 \(pre'_i\)

则交换后序列乘积是 \(pre_{l-1}\times A_r\times (pre'_l)^{-1}\times pre'_{r-1}\times A_l\times suf_{r+1}\)

枚举 \(l,r\) 分别对应的字符,则 \(l,r\) 剩下的矩阵乘积可以分开,维护每种矩阵出现次数,用哈希值存储即可

时间复杂度 \(O(|\Sigma|^2n\log n)\)

D. 爱丽丝猫

环上并不好做,考虑断开的位置,发现最大值比较关键,它所在的段的两边是独立的,考虑这个环的形态,如果钦定最大值后面接顺时针方向的数,则它逆时针方向的一段可以看作去除不选

因此把最大值放在序列最前面,逆时针、顺时针把环拉成链各做一遍,取最大值即可

然后设 \(f(i,j)\) 表示前 \(i\) 个数分成 \(j\) 段的最大值,维护单调栈,可以用线段树维护最大值做到 \(O(nk\log n)\)

做到 \(O(nk)\) 可以继续对这个东西优化,维护这个最值可以用链表维护差分配合并查集找到下一个在链表中的数,做到 \(O(nk\alpha(n))\)

重新考虑单调栈,单调栈中的数单调递减,将它抽象为树结构,每个点的父节点是将它从单调栈中弹出的点,树是动态构建的,此时单调栈中的每个点都作为根

则以点 \(x\) 为新划分区间左端点时,新区间前缀最大值个数是 \(x\) 到根的距离,后缀最大值个数为 \(x\) 的根到单调栈顶部数的个数

这些最大值可以在单调栈弹栈、入栈的时候维护,具体地,维护单调栈中 \(x\) 子树中 \(h1_{x}=\max \{g_y + dep\}\),\(h2_x=\max g_y\),单调栈上前缀 \(f1_x=\max\{h1_y\}\),\(f2_x=\max\{h2_y\}+dis_x\),其中 \(dis_x\) 为 \(x\) 到栈顶距离,复杂度 \(O(nk)\)

标签:2024.10,log,复杂度,矩阵,笔记,Cat,维护,Mouse
From: https://www.cnblogs.com/KellyWLJ/p/18509349

相关文章

  • 学习笔记(十七):ArkUi-气泡提示 (Popup)
    概述:Popup属性可绑定在组件上显示气泡弹窗提示,设置弹窗内容、交互逻辑和显示状态。主要用于屏幕录制、信息弹出提醒等显示状态。一、系统气泡,PopupOptions通过配置primaryButton、secondaryButton来设置带按钮的气泡 1、文本气泡常用于只展示带有文本的信息提示,不带有任何......
  • 《程序员修炼之道——从小工到专家》笔记3
    《程序员修炼之道》作为编程与软件开发领域的经典之作,全面覆盖了程序员成长路径上的关键要素,读后感可归纳如下几个维度:职业心态的塑造:本书着重阐述了程序员必备的职业操守与心态,包括对工作的热情、不懈的求知精神,以及对代码精益求精的态度。这深刻提醒我,技术能力固然是基石,但积极......
  • 《程序员修炼之道——从小工到专家》笔记2
    第四章:实效导向的极致严谨本章深入剖析了程序员在面对复杂性与不确定性时,如何秉持一种“极致严谨”的态度,以确保软件的高品质与可靠性。程序员应对自己的代码保持审慎怀疑,始终预设其可能潜藏错误,直至历经严苛的测试与验证。“极致严谨”在此意指对细节的深切关注及对潜在问题的持......
  • NOIP2023 做题笔记
    NOIP将近,由于我实力太菜,所以只能写写真题提升自己了。P9868[NOIP2023]词典简单字符串题,注意到可以换无限次,所以直接处理出每个字符串中最小的字符数和最大字符数就行了。#include<bits/stdc++.h>#definemxn3010usingnamespacestd;chars[mxn][mxn];intn,m,cnt[mxn]......
  • 2024.10.31 近期练习
    板刷ARC,再不刷就退役了。ARC185AmodMGame2猜结论题,两个人牌的总和是\(n\times(n+1)\)。若\(n\times(n+1)\bmodm=0\)或\(>n\)先手获胜。显然手牌还有大于\(1\)张的时候不可能失败。和取模\(m\)为\(0\)那么后手一定最后一张失败;若取模\(\len\)则后手一直......
  • 2024.10.31
    《代码大全2》是一本编程领域的经典之作,为开发者们提供了丰富且实用的指导。在阅读过程中,关于软件构建的前期准备给我留下了深刻印象。书中强调了需求分析的重要性,这就像是大厦的蓝图绘制。如果对需求理解不清晰或存在偏差,后续的代码编写可能会像没有方向的航行。例如,若开发一个......
  • 2024.10.31..
    《代码大全2》是一部编程领域的瑰宝,为编程者打开了一扇通向高质量代码世界的大门。阅读此书,深刻感受到它对于编程全方位的指导意义。从前期的规划设计到具体的代码编写,再到后期的调试优化,无一遗漏。在设计阶段,它教会我们如何准确把握需求,制定合理架构,避免盲目编码。编写代码过程......
  • 2024.10.31.
    《程序员修炼之道》为程序员们呈现了一条从入门到精通的成长路径,宛如一幅指引前行的地图。书中提到的“注重实效的哲学”让我深思。它强调要以一种务实的态度对待编程,明白每个代码决策背后的价值。例如,在选择算法时,不能仅仅因为某个算法新或者复杂就选用,而要根据实际的业务场景......
  • Java进阶学习笔记64——IO流
    IO流:输入输出流,就是读写数据的。IO流的应用场景:怎么去学习IO流?1、先搞清楚IO流的分类、体系?2、再挨个学习每个IO流的作用、用法。IO流的分类:按流的方向分为:按流中数据的最小单位,分为: IO流总体上来看就有四大流:字节输入流: 把磁盘或网络中的数据以一个个......
  • Java进阶学习笔记63——字符集
    常见字符集介绍:美国人:英文字母(大小写)数字、标点符号、特殊字符。标准字符集:ASCII码:标准ASCII字符集:ASCII:美国信息交换标准代码,包括了英文、符号等。标准ASCII使用1个字节存储一个字符,首位是0,总共表示128个字符,对美国人老说完全够用。中国人自己的字符集:GBK(汉字内......