CF 1100~1500 数论

GCD Partition

题意:

给定长度为 \(n\) 的数组 \(a\)

要求把它分成 \(k(1\lt k\le n)\) 个子段,要求所有子段和的最大公约数最大,求这个最大值。

\(l_i,r_i(1\le l_i \le k)\) 分表示第 \(i\) 个子段的左右端点。这个子段的子段和 \(b_i=\sum\limits_{j=l_i}^{r_i}a_j\)

要求 \(l_i\le r_i\),对于所有 \(1\le j\lt k\),有 \(l_{j+1}=r_j+1\),并且 \(l_1=1,r_k=n\)最大化 \(\gcd(b_1,b_2,...,b_k)\)

分析:

由于是对子段求公共GCD,可知子段和是连续的
假设对于一种分段方式中有 n 段,假设此时的公共 GCD 为 k,显然 k 必定满足是所有段和的约数,接下来合并其中两个段,此时的 n - 1 段仍然满足 k 为每段的约数
立即推:分成 2(k > 1)段时,此时的 GCD 最大

code

Make It Round

题意:

给定 \(n\)\(m\), 我们可以把 \(n\) 变为 \(n\cdot k(1\leq k\leq m,k∈N^{*})\), 请输出末尾 \(0\) 的个数最多的 \(n\cdot k\)

  • 例如, \(481000\)\(1000010\) 末尾 \(0\) 的个数更多
  • 如果有多个末尾 \(0\) 个数最多的 \(n\cdot k\), 则输出其中最大的一个
  • 如果不存在末尾 \(0\) 个数更多的 \(n\cdot k\), 则输出 \(n\cdot m\)

分析:

对于给定的\(n\),若要在末尾产生\(0\),则必须通过与本身因数中的\(2\)\(5\)相乘或者直接乘\(10\)获得
所以应当尽量先消耗\(2\)\(5\)的个数(在\(m\)的范围内取对应的数),最后要保证数尽量的大,所以在取完\(2,5,10\)之后检查是否能继续乘上一个数使数增大

code

posted @ 2023-05-26 13:16  347Foricher  阅读(3)  评论(0编辑  收藏  举报