// 鼠标点击特效 //

Educational Codeforces Round 173 (Rated for Div. 2)

upd:2024/12/18 更新了 G

A

硬币肯定是能拆则拆。时间复杂度 O(Tlog4n)

B

分类讨论 5 个奇数:

  • 对于 1 ,肯定可以整除。
  • 对于 3 ,可以整除 n 要求 n 的数位之和为 3 的倍数。也就是 dn!0(mod3) 。发现当 n3 的时候,n! 已经是 3 的倍数肯定满足条件。如果 n<3 ,直接计算是否是 3 的倍数即可。
  • 对于 5 ,要求 d=5
  • 对于 7 ,发现 1111117 的倍数,也就是说一旦 n!6 的倍数也就是 n3 ,那么肯定满足条件。如果 n<3 ,直接计算是否是 7 的倍数即可。
  • 对于 9 ,做法类似于 3
    时间复杂度 O(T)

C

假设全部的数字都满足 ai{1,1} ,此时的答案可以取哪些数?

求出最大,最小子段和(可以为空),设他们的值分别为 mn,mx 。可以证明的是,答案可以取遍 [mn,mx] 之间的任何数。证明:

  • 取最大子段和的全部前缀(可空),至少可以取遍 [0,mx] 之间的任何数。

  • 取最小子段和的全部前缀(可空),至少可以取遍 [mn,0] 之间的任何数。

现在加入 ap{1,1} 。那么对于 a[1,p1]a[p+1,n] 的答案都可以通过上述算法解决。

剩下的就是那些 lpr 的区间了。我们求出包含 p 的最大子段和 mx 和最小子段和 mn ,那么答案也可以取遍 [mn,mx] 之间的任何数,证明类似。求的具体方法就是求出 ap1 结尾的最大/最小后缀和 ap+1 开头的最大/最小前缀和。

将满足条件的数排序并去重即可。时间复杂度 O(Tnlogn)

D

求出一个极大的区间 [x,y] 满足 lxGyGr 。接下来问题转化为了找到两个值 p,q[x,y]gcd(p,q)=1 ,最大化 |pq|

直接猜 p[x,y][x+logy]q[x,y][ylogy,y] 然后过了。时间复杂度 O(Tlog3V)

(bro把 log40 然后赛后被hack了,但是开到 64 即可通过)

E

这个题目很好!

首先二进制问题是可以拆位的,问题转化为了01矩阵问题。我们可以进行的操作有:行涂 0 ,列涂 1 ,问矩阵 A 是否可以变成矩阵 B ?

假设不考虑 A 的状态,仅考虑 Bi,j 的状态:

  • Bi,j=1 ,那么第 i 行涂 0 应该在第 j 列涂 1 之前操作。

  • Bi,j=0 ,那么第 i 行涂 0 应该在第 j 列涂 1 之后操作。

如果将上述关系连边,最终是一个 DAG 就有解。这真的对吗?

我们发现错误原因在于认为每一行,每一列都操作,但是这是不对的。我们引入一个超级源点,连向哪些必要操作的点(Ai,jBi,j):

  • Ai,j=0,Bi,j=1 ,则必须进行列涂 1 ,源点向其连边。

  • Ai,j=1,Bi,j=0 ,则必须进行行涂 0 ,源点向其连边。

仅考虑超级源点可以到达的点构成的导出子图,如果是一个 DAG 就有解。现在很对。

对于每一个二进制位都判断以下,时间复杂度 O(n2logV)

F

动态dp题,出的很烂。问题取反面:选取不为空的,尽量小的集合使得异或和为 0

考虑问题放到线段树上,每一个节点维护 fi 表示异或和为 i 的最小节点数,gi 表示可以到达最小节点数的方案数。容易在 O(log2V) 的时间内合并两个节点。

则直接使用线段树来做,预处理 O(nlog2V) ,查询 O(qlognlog2V) ,无法通过。

考虑猫树分治,预处理是 O(nlognlogV) ,查询 O(qlog2V)

G

这个题目的做法很有参考价值!

我们考虑分块去做。将答案拆分为块内的答案和块外的答案。只要维护了 sumi,j 表示元素 i 在前 j 个块中出现的次数,配合一个桶很容易去以 O(nB) 的时间去计算块外的答案(在已知块内答案的基础上),其中 B 是块长。

对于块内的问题,我们考虑直接维护数组 fi,j 表示第 i 个块到第 j 个块的答案。可以直接以 O(n2B) 的时间暴力预处理,考虑点修对 f 的影响:转化为减少某一个元素/添加某一个元素。这里拿添加元素举例。

假设添加元素 v 的下标所在块是第 x 个块,则对于 ixjfi,j 的权值应该增加 sumv,jsumv,i1 ,蛮力维护的时间为 O(n2B2) ;我们还需要维护 sum 本身的变化,直接蛮力维护时间复杂度为 O(B)

现在分析一下时间复杂度,预处理为 O(n2B) 。对于询问,如果是点修,时间复杂度为 O(B+n2B2) ;区间查询时 O(B) 。发现取 B=n23 时最优秀的,时间复杂度来到了 O(Qn23)

但是很遗憾,这是无法通过的。

我们想一下哪里不优的?明明两种询问的操作次数可以被视为相同,但是在点修时,维护 f 花了 O(n2B2) 的时间,而在查询时,只花费了 O(1) 的时间去调用 f

考虑将 fi,j 增加 sumv,jsumv,i1 转化为增加 (sumv,jsumv,x)+(sumv,xsumv,i1) .前后部分分别维护,拿前半部分举例,我们枚举 j ,对于一个相同的 jfix,j 都需要增加 sumv,jsumv,x ,直接将贡献打在差分数组上。查询的时候暴力计算差分数组的前缀和,因为差分数组只有 O(nB) 这么大。

至此,点修的时间复杂度被优化到 O(B+nB) ;区间查询的时间复杂度变慢了,是 O(B+nB) 。容易看出 B=n 时最优,时间复杂度为 O(Qn)

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