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

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

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

题目大意: 对一个长为 n n n的数列 { a n } \{a_n\} {an},有以下两个操作:
1. 1. 1.求和操作:数列 { a 1 , a 2 , . . . , a n } \{a_1,a_2,...,a_n\} {a1,a2,...,an}变为 { a 1 , a 1 + a 2 , . . . , a 1 + a 2 + . . . + a n } \{a_1,a_1+a_2,...,a_1+a_2+...+a_n\} {a1,a1+a2,...,a1+a2+...+an}
2. 2. 2.翻转操作:数列 { a 1 , a 2 , . . . , a n } \{a_1,a_2,...,a_n\} {a1,a2,...,an}变为 { a n , a n − 1 , . . . , a 1 } \{a_n,a_{n-1},...,a_1\} {an,an1,...,a1}
给定两个长为 n n n的数列 { a n } \{a_n\} {an} { b n } \{b_n\} {bn},问能不能对 { a n } \{a_n\} {an}进行有限次数的上述操作,使得整个数列各项和 { b n } \{b_n\} {bn}中的各项对应相等。如果能,输出最小操作次数,否则,输出 − 1 -1 1
你需要在 1 s 1s 1s内解决 T T T组数据。
数据范围: T ≤ 20 , n ≤ 1 0 5 , 1 ≤ a 1 , . . . , a n , b 1 , . . . , b n ≤ 1 0 12 T\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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值