本文主要是介绍DTOJ 4781. 抗疫斗争,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题意
新冠疫情爆发以来,病毒不断地扩散传播,而人类也在不断采取各种措施遏制病毒传播。于是我们可以为这场抗疫斗争建立一个数学模型,将病毒的不断传播和人类的不断采取措施抽象为一场双方轮流行动的博弈。我们认为人类与病毒的每轮行动都可以选择一个正整数作为行动值来评估。然而,出于各方面限制,双方的所有行动值总和必须等于一个数 m m m,且每次的行动值不能超过对方上轮的行动值。对人类来说,要遏制疫情,就应成为最后行动的一方,也就是说,在本方的某次行动后,行动值总和 m m m 恰好被消耗完。
假设人类先行动,那么我们只需一鼓作气消耗完所有 m m m 点行动值,就能战胜病毒。然而在最开始的阶段出于认识不到疫情的严重性,往往最难开展大规模行动。出于这个原因,我们令 h m h_m hm 表示在行动值总和为 m m m 的情况下,人类(即先行动方)的第一次行动最少要多少行动值,才能保证自己必胜。
出于统计需要,某科学家记 f i = ∑ m ∣ i h m f_i=\sum_{m|i} h_m fi=∑m∣ihm,并想知道 ∑ i = 1 n f i \sum_{i=1}^{n} f_i ∑i=1nfi。方便起见,对 998244353 998244353 998244353 取模。你能帮个忙吗?
子任务编号 | $n\le $ | 分值 |
---|---|---|
1 1 1 | 3 3 3 | 1 1 1 |
2 2 2 | 1000 1000 1000 | 9 9 9 |
3 3 3 | 1 0 5 10^5 105 | 31 31 31 |
4 4 4 | 1 0 11 10^{11} 1011 | 28 28 28 |
5 5 5 | 5 × 1 0 13 5\times 10^{13} 5×1013 | 26 26 26 |
6 6 6 | 1 0 15 10^{15} 1015 | 5 5 5 |
题解
首先容易猜想并用归纳法证明 h m = 2 l o w b i t ( m ) − 1 h_m=2^{lowbit(m)-1} hm=2lowbit(m)−1,于是枚举 2 i 2^i 2i,它对每个倍数 f f f值的贡献都是 2 m a x ( i − 1 , 0 ) 2^{max(i-1,0)} 2max(i−1,0)(本来想的是只对奇数倍数贡献 2 i 2^i 2i,但这样也是对的并且形式比较优美),直接数论分块的效率就是 O ( s q r t ( n ) ) O(sqrt(n)) O(sqrt(n))的,但常数略大过不去。
有一个比较神奇的做法,考虑转移到坐标轴上,即为反比例函数在第一象限与 x , y x,y x,y正半轴围成的部分的整点数。发现可以这个部分与直线 y = x y=x y=x对称比较优美,可以把它分为左下角为顶点,边长为 s q r t ( n ) sqrt(n) sqrt(n)的正方形与两个全等三角形,于是暴力枚举前 s q r t ( n ) sqrt(n) sqrt(n)的答案,乘上2再减去正方形即可。
这篇关于DTOJ 4781. 抗疫斗争的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!