[LeetCode]周赛335 Problem 3-Solution_每日热点

2023-03-05 12:17:03 来源:哔哩哔哩

题目简述

给定一个长度为的序列,将其分为前后非空两段,使得前后两段的乘积互质,并输出分割点。如果分割点不存在,输出。

原题目链接:https://leetcode.cn/contest/weekly-contest-335/problems/split-the-array-to-make-coprime-products/

思路1

如果直接从左到右枚举分割点,并维护左右乘积,看似复杂度合理,但由于数值过大,必须使用高精度gcd,这样实际的复杂度(包括时间和编程难度)都很大。


(资料图片)

一般对于gcd,可以从因子来考虑。我们将中的所有数分解质因数,然后枚举分割点并维护左右乘积的分解结果就可以了。只要使用合理的维护技巧(见附录),复杂度可以做到。其中是筛素数的复杂度,。

由于质数数目的特性(),因此以内的素数数目也是万级别,因此也不妨尝试直接暴力维护乘积,复杂度为。如果不放心,可以使用bitset(比如我)优化到。

思路2(未验证)

在得到中的所有数的质因数分解后,从右到左枚举每一个数,与此同时维护当前每一个质因子在数组中出现的最小下标。这样我们可以得到对于每一个数而言,其后首个与它不互质的数的位置。这样,在之间不可能存在分割点。我们标记这整个区间内的位置为impossible。最后,枚举分割点,找到最小的非impossible的分割点即可。

注意到每次标记一个连续的区间,因此使用差分进行标记,复杂度为。

备注:当然,其实也没必要标记,可以直接根据一直往后“跳”就可以了。

附录

关于思路1中的维护策略。很简单,只需要考虑每一个数所涉及的个质因子即可。用一个cnt变量记录当前左右公共质因子数目,在更新中动态调整cnt。

后记

本来是想试一试leetcode的周赛如何,看看能不能二十分钟解决战斗。结果被T3安排了,写思路2WA傻了:

于是就有了这个solution,卧薪尝胆。复健是复健不了了,快乐竞赛。        

代码比较简单就不给了。

关键词: 就可以了 从左到右 可以使用

推荐内容