2023.10 做题记录

  1. LOJ10185

    fi 表示将前 i 个任务分成若干组的最小费用,由于分的组数不确定,所以把 s 在每次分组时对答案的影响提前计算。记 Ci=j=1ici,Ti=j=1iti,有转移 fi=min0j<i[fj+Ti×(CiCj)+s×(CnCj)],时间复杂度 O(n2)

  2. LOJ10185

    斜率优化模板题。将上式化为 fiTi×Cis×Cn=0j<i(fjs×CjTi×Cj),形如 y=kx+b 的变形 bi=yjkixj,将关于 j 的信息看作点,等同寻找点 (xj,yj) 使得最小化斜率为 ki 的直线的截距 bi,由于 x,k 均单调,用单调队列维护下凸壳即可。时间复杂度 O(n)

  3. LOJ10186

    斜率优化模板题。此时 k 不再单调,单调栈维护凸包,在凸包上二分即可。注意 x 不严格单调时要判相等,按无穷大处理。时间复杂度 O(nlogn)

  4. P4027

    斜率优化模板题。设 fi 表示到第 i 天的最大钱数,易得第 j 天能买入的两种金券数分别为 Xj=fjrjajrj+bj,Yj=fjajrj+bj,于是有转移 fi=max{fi1,max1j<i(aiXj+biYj)},边界为 f0=s

    只由前项转移是容易的,先看后项。变形为 fibi=max1j<i[Yj(aibi)Xj],然而 ki,xj 不单调,使用 CDQ 分治。最直接的想法是对于区间 [l,r],先递归处理 [l,mid],然后对其按 xj 排序后建凸包,再转移右边,转移时凸包上二分 ki,递归到叶子时转移 fifi1。时间复杂度 O(nlog2n)。实际上可以分治前先按 ki 排序,每次分治时,先将区间按原位置分成左右两半,以保证转移方向正确,再递归处理左半边,并在转移结束后按 xj 归并排序。此时左半边 xj 单调,右半边 ki 单调,于是转移做到线性。时间复杂度 O(nlogn)

  5. CF311B

    预处理 di 表示第 i 座山与第 1 座山的距离,那么第 i 只猫能被出发时刻为 x 的人接走的充要条件是 xdhiti,不妨令 ci=dhiti 并升序排序。设 fi,j 表示前 i 只猫被前 j 个人接走,等待时间之和的最小值,初始有 f0,i=0。令 si=j=1ici,有 fi,k=min0j<i[fj,k1+(ij)ci(sisj)],斜率优化即可。

  6. P1379

    注意到状态容易记录,可以用 A* 做,用 unordered_map 存已有答案。考虑到每次交换会使被交换数字向目标位置靠近至多一步,于是将估价函数设为所有数字与其目标位置的曼哈顿距离之和。

  7. P2901

    A* 做法的 k 短路模板题。估价函数设为到终点的最短路,前 k 次取出 t 点时的 dis 为答案。另外有一个剪枝,s 到每个点距离的前 k 小距离才有可能是答案的一部分,记录一下更新次数即可。

  8. P1784

    预处理 popcount 和对数值,维护每行、每列和每个宫格内的数字情况。优化搜索顺序,于是每次优先取出填数方案最少的格子进行填数。

  9. P1120

    剪枝。第一,优化搜索顺序,降序排序,按 ai 从大到小顺序枚举;第二,枚举的原长 lenai 和总长之间,且为总长的因数;第三,跳过已使用的或加上之后超出组内限制的;第四,跳过长度相同的,避免重复计数;第五,若一根木棍是该组内的第一根或最后一根且无解,则后面不论怎么选都一定无解,可以反证;第六,组内保证长度降序,维护一个指针,同组内不再取长度更大的木棍。然后可以通过此题。

  10. P1731

    剪枝。记第 i+1m 的面积和体积分别为 s,vans 为当前最优解。第一,ri[i,min{ri+11,nv}]hi[i,min{hi+11,nvri2}],从大到小枚举以优化搜索顺序;第二 s+j=1i2j2nv+j=1ij2<ans

    第三,考虑前 i 层面积之和 Si 与体积之和 Vi 之间的关系,有:

    Si=j=1i2rjhj=2ri+1j=1irjhjri+1>2ri+1j=1irj2hj=2ri+1Vi

    又由于 Vi=nv,Si+s<ans,有 s+2(nv)ri+1<s+Si<ans,整理得 2(nv)<ri+1(anss1)。然后可以通过此题。

  11. UVA529

    注意到每扩展一项至多是前一项两倍,而要求项数最少,那么项数一定不会很多,考虑迭代加深,再加一些剪枝。第一,ax=ai+aj,降序枚举 1ij<x,以优化搜索顺序;第二,设深度上限为 dep,那么 ax×2depx<n 时必定无解,由于降序枚举,直接退出内层循环;第三,若 axax1,同上;第四,若 px>n,跳过。然后可以通过此题。

  12. UVA1343

    步数不会很多,而估价函数直觉上好设计,考虑 IDA* 做。具体地,注意到每次移动至多会使中间区域的目标数字增多一个,估价函数设为中间区域出现最多的数字还缺几个即可。此外,记录上一次操作,这一次不进行与上次操作互逆的操作。

  13. UOJ22

    首先有一个性质,对一些数依次取模,若一个模数不是严格的前缀最小值就无效,即有效的 ai 一定严格递减。于是先对 ai 降序排序,发现除了 an 之外的数都可以随意选择模或者不模,因为可以丢到更小的数后面。

    fi,j 表示对前 i 个数取模,能得到 j 的方案数,初始有 f。考虑转移,若取模,有 fi,jmodaifi1,j;若不取模,可以钦定 ai 在最终方案中是在紧跟在哪个 aj 后面,j[i+1,n] 中的任意一个都可以,于是方案数就是 ni,转移为 fi,jfi1,j×(ni)。时间复杂度 O(nx)

  14. CF464E

    以下记 Vx 上界。考虑在边权为 2x 的情况下维护 Dijkstra 这一过程,实际上只有 dis 的比较、赋值和相加这三种操作,还需要一个堆(也基于比较)。尝试用线段树维护每个 dis 的二进制表示,加上 2x 就是找 x 开始最低位的 0,设这个位置是 pos,相当于 [x,pos) 区间赋 0pos 单点赋 1,赋值操作可以快速实现。比较大小可以线段树上二分,每次优先比较右子树是否相同,到达叶子直接比大小,这一点可以用哈希实现(base 和模数分别取 2109+7,最终 dist 的哈希值就是答案)。此外,还有一个赋值操作,由于 v 由邻接的 u 转移,将线段树做可持久化即可,区间赋 0 可以转为连接 diss 对应位位置的子树。另外,priority_queue 不支持内部修改,每次只有插入和删除才会重新排序,于是替换为 set,松弛某点时,若该点在 set 中,将对应二元组删去,再加入新的。

    还剩下树上找 x 开始的第一个 0 的位置 pos。考虑以下二分过程:若当前区间 [l,r][x,pos) 交集为空或全为 1,返回 1;若当前区间全为 0,返回 max{l,x};否则递归左子树判断是否有解,无解再递归右子树。现在证明这一过程的时间复杂度为 O(logV):尝试构造最坏情况,询问区间为 [1,V1],序列只有第 0 项和第 V1 项为 1,这时所有不被询问区间包含但与询问区间有交的区间有 O(logV) 个,是从根节点开始一直向左或向右的链的拼接;除此之外,无解的区间均为这两条链挂的节点,同样是 O(logV) 个,会 O(1) 跳过;最后会在右侧链一直向下找到答案叶子。得证。综上,该做法有 O(mlognlogV) 的时间复杂度和 O(mlogV) 的空间复杂度。

  15. CF703D

    区间异或和等同于区间出现奇数次的数的异或和,那么出现偶数次的数的异或和就是区间出现过的数的异或和异或上区间异或和,类似区间颜色数,记 prei 表示 ai 上次出现的位置,对询问离线做双指针即可。时间复杂度 O(nlogn+m(logn+logm))

  16. P3175

    xi 表示第 i 位变为 1 的期望次数,所求为 E(maxiUxi)。考虑 minmax 容斥,有 E(maxiUxi)=SU(1)|S|1E(minjSxj),然后对于 min 的部分,有

    E(minjSxj)=1STpT=11ST=pT=11T(US)pT

    f(S)=TSpT,即子集和,做高维前缀和即可。然后原式化为 E(maxiUxi)=SU11f(US),注意去掉 S 为空的情况,以及 Sf(US)=1 时无解。时间复杂度 O(n2n)

  17. CF1119F

    首先考虑 x 固定的时候怎么做,设 fu,0/1 表示保留 / 不保留边 (u,fau) 时,让子树 u 符合度数限制的最小代价。对于 u 的子节点 v,若删边 (u,v),代价为 fv,0+wu,v,否则为 fv,1。转移 fu,0 至少要删 dux1 条与子节点的连边,fu,1 则为 dux,那么一个 v 删相对不删而言的代价为 fv,0+wu,vfv,1,用堆维护这个差值,在删边限制以外的就取 fv,0+wu,vfv,1 的较小值。时间复杂度 O(nlogn)

    现在 x0n1,考虑 x 变大时利用之前的信息,把复杂度摊下来。注意到对于所有 xdu 的情况,u 不受限制了,那么 u 没用了,这样的 u 把原树划分成若干个连通块,u 成为这些连通块的叶子,每次只需要在每个连通块重新做 DP。u 被删时要处理剩余贡献,对于每个父节点 vu 的差值变成 wu,v,插到 v 的堆里,u 的贡献就做完了。

    对每个连通块做 DP 时,堆里会有两类元素,无用点和有用点。无用点 v 的贡献始终留在堆里,因为一直是 u 的儿子;而有用点的贡献仅在这一轮有用,因为后面可能变为无用点,树形态发生变化。每次算 uf 时,需要堆的前若干小元素和,算完后还应当把所有在这轮插入的有用点的贡献从堆中删掉,维护两个堆分别表示插入和删除,插入元素放进前者,删除元素放入后者,求堆顶时先把两堆顶部相同去除。关于时间复杂度,u 被删时会向相邻点 v 的堆中插入,这是 O(dulogdu) 的,而作为有用点向父节点有贡献的次数为 du1 次,由于度数之和为 2n2,故时间复杂度为 O(nlogn)

  18. P2973

    记爆炸概率为 p,设最终在点 u 爆炸的概率为 fu,由于 fu 不容易直接转移,考虑设 gi,u 表示炸弹在 i 时刻到达 u 点的概率,有 fu=pi=1gi,u,又因为 i>1gi,u=1pdu(u,v)Egi1,v,于是有:

    fu=p×g1,u+1pdu(u,v)Epi=1gi,v=p×g1,u+1pdu(u,v)Efv

    高斯消元即可。

  19. P2447

    高斯消元解异或意义下的线性方程组。用 bitset 维护矩阵每一行,若有自由元就继续加入方程,直到解唯一,m 个方程都加入后仍有自由元则解不定。时间复杂度 O(n2mw)

  20. CF893E

    x 质因数分解,每个质因子之间独立,记 x=piαi,对于每个 pi 相当于 αi 个球放 y 个桶允许空的方案数,即 (αi+y1y1),而正负号的方案数是选任意偶数个负号的方案数之和,为 2y1,故答案为 2y1(αi+y1y1)。时间复杂度 O(V+qVlnV)

  21. CF567E

    正反图跑最短路求出所有 diss,u,disu,t,以及以点 u 为终点和起点的最短路个数 cnts,u,cntu,t,一条边 (u,v,w) 为最短路上必经边的充要条件为 cnts,u×cntv,t=cnts,t,其余情况分类讨论强制经过改变是否导致 s 无法到达 t,以及能到达情况下需要修改成的边权的正负性即可。最短路数目可能很多,取模即可。

  22. P4683

    最小化答案需要最小化添加和删除次数,那么需要有公共前缀的串打印次序相邻。对所有串建 Trie,不考虑最后选择不删的字符,贪心方案就是按 DFS 序遍历 Trie,最后在某个叶子结束;现在考虑选择哪些字符不删,于是在最深的叶子结束,DFS 时优先遍历不含这条长链的子树即可。

  23. P2446

    一个想法是先求所有点的最短路,再按照保护关系跑 SPFA,被保护的点的 disv 对其保护点的 disumax,错误之处在于求 disu 的过程中很可能经过被 u 保护的点,导致距离偏小。不妨直接在 Dijkstra 的过程中实现先破坏点的保护点再用该点松弛其他点这一过程,维护每个点在保护图的入度,u 被取出优先队列后松弛原图邻点,若被松弛点的入度为 0 说明不受保护点限制,将其入队,松弛结束后再处理对被 u 保护的点更新 max 并减少其入度,入度变为 0 则入队。时间复杂度 O(mlogm)

  24. HDU4035

    树上高斯消元。记 u 回到 1 号点的概率为 pu,走出迷宫概率为 qu,记 ru=1puqu。设从 u 走出迷宫的期望次数为 fu,容易得到 fu=pif1+(u,v)Erudu(fv+1),由于所有的 (u,v) 均有父子关系,将 fu 设为关于 ffauf1 的线性表示,即 fu=Auffau+Buf1+Cu,代入 fv 并整理得:

    fu=ruduruvuAvffau+dupu+ruvuBvduruvuAvf1+duru+ruvuCvduruvuAv

    从叶子开始向上做系数递推即可。最后有 f1=C11B1。时间复杂度 O(n)

  25. P5643

    minmax 容斥,设 fu,S 表示从 u 出发,首次到达 S 中某点的期望次数,每次询问的点集 S 的答案为 TS(1)|T|1frt,TuS 时有 fu,S=(u,v)Efv,S+1du=ffau,Sdu+vufv,Sdu+1,否则 fu,S=0,树上高斯消元可对每个 S 做到线性。询问实际是对所有 frt,S 做子集和,高维前缀和即可。时间复杂度 O(n2n)

  26. BZOJ2554

    假设已经知道最终染成哪种颜色,那么其他颜色无区别,可看做所有白球最终被染成黑球,于是设 gi 表示一种颜色有 i 个球,最终所有球变为这种颜色的概率,以及 fi 表示一种颜色有 i 个球,钦定所有球变为这种颜色的情况下的期望次数。

    首先有 g0=0,gn=1,且 gi=i(ni)n(n1)gi1+i(ni)n(n1)gi+1+i(i1)+(ni)(ni1)n(n1)gi,整理得 gi=gi1+gi+12,为等差数列,故 gi=in

    关于 f,一个直接的想法是类似 g 一样,只多加一个 1 的次数,化简得 fi=12fi1+12fi+1+n(n1)2i(ni),然而这是错的。原因在于 f 是建立在所有球变为黑色的基础上的条件期望,球有 i1 个和 i+1 个的情况下的 g 并不一样,因此要加一个概率的权,实际上为 fi=i12ifi1+i+12ifi+1+n(n1)2i(ni。然后表达为后一项的线性表示,做系数递推即可。最终答案为 fcntcgcntc,时间复杂度 O(n)。(关于概率影响的系数,可以用抛硬币的例子理解,抛三次硬币两正一反的情况下,第一次的概率并不是正反相等)

posted @   Zwb0106  阅读(1)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示