(2020-10-7编写)一道有趣的不难的题

本文探讨了一道关于数列操作的数学题目,涉及数列的求和与翻转操作。通过分析,作者指出经过一次求和操作后的数列必然单调递增,而连续翻转两次没有意义。提出从目标数列反向推导,通过判断单调性和执行操作来寻找匹配原数列的可能性,算法复杂度为O(nlog1012)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

没错,这篇文章不是在我学OI时写的,而是在实实在在的2020年写的。这似乎预示着我将不得不重回竞赛的怀抱了,祝我好运吧。

题目大意: 对一个长为nnn的数列{an}\{a_n\}{an},有以下两个操作:
1.1.1.求和操作:数列{a1,a2,...,an}\{a_1,a_2,...,a_n\}{a1,a2,...,an}变为{a1,a1+a2,...,a1+a2+...+an}\{a_1,a_1+a_2,...,a_1+a_2+...+a_n\}{a1,a1+a2,...,a1+a2+...+an}
2.2.2.翻转操作:数列{a1,a2,...,an}\{a_1,a_2,...,a_n\}{a1,a2,...,an}变为{an,an−1,...,a1}\{a_n,a_{n-1},...,a_1\}{an,an1,...,a1}
给定两个长为nnn的数列{an}\{a_n\}{an}{bn}\{b_n\}{bn},问能不能对{an}\{a_n\}{an}进行有限次数的上述操作,使得整个数列各项和{bn}\{b_n\}{bn}中的各项对应相等。如果能,输出最小操作次数,否则,输出−1-11
你需要在1s1s1s内解决TTT组数据。
数据范围:T≤20,n≤105,1≤a1,...,an,b1,...,bn≤1012T\le 20,n\le 10^5, 1\le a_1,...,a_n,b_1,...,b_n \le 10^{12}T20,n105,1a1,...,an,b1,...,bn1012

做法: 本题是一道思维题。
注意到一开始数列中的项都是正整数,因此在进行一次求和操作后,整个数列必定是单调递增的。算上翻转操作,我们可以断定,只要进行过一次求和操作,则整个数列要么单调递增,要么单调递减。而连续进行两次翻转操作就和没翻转一样,所以最优的操作方法一定是求若干次和,然后翻转一次,然后继续往下,这样。
我们发现两种操作都是可逆的,也就是说,如果我们知道一个数列{an}\{a_n\}{an}经过一次求和或翻转后,得到一个数列{bn}\{b_n\}{bn},而{bn}\{b_n\}{bn}已知,我们可以用O(n)O(n)O(n)的时间求得{an}\{a_n\}{an},且很显然,{an}\{a_n\}{an}是唯一的。那么与其正着算,还不如从目标序列{bn}\{b_n\}{bn}一步步倒回去,看它会不会在某个时刻和{an}\{a_n\}{an}相等。
如果{bn}\{b_n\}{bn}单调递减,则它的前一步一定不是求和(因为求和操作后得到的数列必然是单调递增的),所以前一步只能是翻转,于是将它翻转过来,操作次数+1+1+1
如果{bn}\{b_n\}{bn}单调递增,则它的前一步可以是求和,也可以是翻转,但如果前一步是翻转,那么再前一步一定也是翻转(因为翻转一次后数列单调递减),前面说过连续翻转两次没有意义,因此有意义的前一步必然是求和,这时就对数列求一个差分(求前缀和的逆操作),操作次数+1+1+1
这样循环下去,中间一直判断得到的每一个数列是否与{an}\{a_n\}{an}相等,如果相等就立刻退出,输出操作次数即可。如果某个时刻{bn}\{b_n\}{bn}不单调了,那它要么就和{an}\{a_n\}{an}相等,要么就翻转一次后,和{an}\{a_n\}{an}相等,否则,我们就能得出无解的结论,输出−1-11
这是一个可行的算法,那么它的时间复杂度如何呢?注意到连续多次求前缀和,数列中最大项的大小是指数级增长的,而目标序列中最大项也不会超过101210^{12}1012,所以如果有解,那么求和次数最差也就是log⁡1012\log 10^{12}log1012。而连续两次翻转是没有意义的,因此翻转最多只能夹在两次求和之间,所以最差也是log⁡1012\log 10^{12}log1012次。所以上述循环的深度最多达到log⁡1012\log 10^{12}log1012这个等级,而里面的差分、翻转都是O(n)O(n)O(n)的,因此整个算法的时间复杂度为O(nlog⁡1012)O(n\log 10^{12})O(nlog1012)。事实上要比这个数小不少,因为log⁡\loglog的底数一般比222大很多。
这样我们就解决了这个问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值