1674
关键问题在于如何确定最终互补的数?
这或许是一个需要遍历的变量,设为x
考虑原数组的min和max,那x是否应该<=max+min
应该是的,因为如果x>=min+max的话,那说明其它的所有组合也都不能直接满足?吗?
不对,只能说最大的情况该是第一大和第二大?
不是,是要问修改的最少次数
如果x>=min+max,那么剩下的min和max,加起来可能会达不到,也不一定
可能出现倒数第二大和第二大加起来比倒数第一大跟第一大加起来大的情况
那如何确定这个x的遍历上下界?
不对,组合不是自由的,就是固定的i和n-1-i,之前想复杂了
那么考虑先把遍历一次求个和,
这样会得到一个n/2的数组,那么最终求和结果应该在这里面的最大值和最小值之间
对于每个数据对,其修改范围都在一定范围内
优先考虑选择n/2数组中,已有求和结果相同最多的,但如果都不相同?
或者这个最多的就一定是答案吗?
如果说用差分数组
首先一开始的思想,还是枚举最后的求和结果T,
对于每个T遍历n/2次,
然后看num[i]和num[n-1-i]的和与T的关系
如果T刚好等于,那么可以减少两次修改,积累的修改数是0
如果不是的话,要进行替换时,由于是直接替换为1到limit之间
所以对于每对,只替换一次的情况就是T在a+1和a+limit之间,即替换掉B;或者b+1和b+limit之间,即替换掉A
这是只替换一次,减少一次修改,积累的修改数是0
对于其它情况,就是在2和2limit之间,要么就是不存在无法修改
这是直接遍历,
最大的结果就是修改N次,即全都要修改,或者压根不存在,可作为暴力法的剪枝
那么要求最少的次数,就是min(res,N)
不过T的取值范围是什么?假设求得T的取值范围X
那么直接遍历的复杂度就是X*N/2
那差分数组和这个题有什么关系?如何实现的优化?
A
就是说,原来遍历T时,是逐个访问A和B来知道能优化多少操作的
但是数组是已经给定,已经已知的了,所以可以知道对于每个数据对
能够在T的取值范围内,对多少范围的T取值造成影响
就是说给定一个数据对(a,b),那么就可以知道
1.它在T=a+b的地方能优化两次
2.在[a+1,a+limit]和[b+1,b+limit]的区间内能优化一次
其余的用管吗?
以及如果a和b的影响区间有重合该怎么办?是否意味着在那个重合区间当中能优化两次?这显然是不对的吧?那如果有重合该怎么处理?
A1
这里确实要处理掉区间重合的问题
A2
最后访问这个优化数组当中的最大值即可,数组的下标就是T,即顶的最后加和
值就是可以优化的次数,最终的操作次数就是N-优化的次数
差分数组的优化就是优化对区间的修改,即不是一个一个修改[a+1,a+limit]而是修改两个端点
最后通过求前缀和得到最终结果值
B
但是依然还有一直没解决的问题,T的取值范围如何确定?

看取值范围,nums[i]在1和limit之间,所以可修改的范围,一定大于nums[i]的取值,那么两次修改,一定可以覆盖原数组的加和
所以T的取值就是该两次的最小值和最大值,那么原数组的加和就一定在这个范围当中
即[2,2limit]
Final
那就是初始化一个数组T,范围为[2,wlimit],而且还是差分数组
for循环n/2次
对于下标i和n-1-i上的值a和b
判断区间之间是否重叠,如果重叠,就合并,即取最小和最大
然后修改一个区间,即两个点即可
如果不重叠
就修改四个点

C
如何合并区间?对于(a,b)和(c,d)
判断a<c&&b>c
如果是,就是合并区间(a,d),
c<a&&d>a
如果是,就是合并区间(c,b)
如果都不是就是4个区间
如果a=c呢?
如果b=c或d=a呢?

刚才的合并有纰漏,就是这里,在整数点上相邻,那么即使不重合,也是可以合并的

Test

cd /workspaces/miniob/test/case
python3 miniob_test.py
python3 miniob_test.py --test-cases=basic
./build/bin/observer
CREATE DATABASE test_date;
USE test_date;
CREATE TABLE date_table(id int, u_date date);
INSERT INTO date_table VALUES (1,'2020-01-21');
SELECT * FROM date_table;
SELECT * FROM date_table WHERE u_date>'2020-1-20';
EXIT;