此题代码很长待我闲的蛋疼的时候再来写。。。。
思路:
首先我们考虑一个3元组q(hj,min(h[j-1],h[j+1]),max(h[j+1],h[j-1]);
然后我们复制一个数组记为k[],原数组记为h[];
每个数组代表的是三元组不只是一个高度。
稍微分析一下交换h[i],与h[k]的话只有|h[i-1]-h[i]|,h[i+1]-h[i]|,对于k同理,所以只有4个值受影响。一般我们遇到绝对值都是要打开的。
所以考虑 1.h[k]<min(h[i-1],h[i+1])2. h[k]>max(h[i-1],h[i+1]).3.h[i-1]<h[k]<h[i+1]对于i同理
所以要考虑9中情况。然而对于.h[k]<min(h[i-1],h[i+1]) 和.h[i]<min(h[k-1],h[k+1])你把绝对值打开发现他们的和是没有变的,其他还有3中情况是一样的。
所以只考虑6中情况。
其实6中情况中我们只需再考虑2种情况的处理方法就好了,其他4种的处理方法都和2种中的一种一样。
1.h[i]<min(h[k-1],h[k+1])与h[k]>max(h[i-1],h[i+1]).
先让k数组用最小值排序从小到大。
然后让h数组用实际高度排序。然后对于每个高度。首先二分在k数组中找到满足h[i]<min(h[k-1],h[k+1])的那些范围很明显是连续的。
然后将那些范围里的数插入线段树(当然树状数组貌似也阔以)线段树 位置是高度的值 每个位置代表的值是这个情况改变后的值,(因为我们要在线段树上求最大值嘛。)
然后在线段树上查找满足h[k]>max(h[i-1],h[i+1])的哪些k的最大值。
到下一个i的时候还是先找出范围,然后将那些不在范围内的k从线段树中去掉。注意(我们在去掉的时候是k数组中从小到大去掉的,这就是我排序的原因)
你还阔以发现,由于i也是排了序的所以每变换一个i高度都是增加的,对应的范围都是连续减小的。
然后再找最值就好了。
2.h[i]<min(h[k-1],h[k+1])与min<h[k]<max(这个有点变化,所以我们考虑怎样用上面的方法,所以必须要转换下思维)
这中情况只能是用k的min排序,用i的h排序,然后用h[i]插入线段树。其他操作和上面一样。
总结做法就是:
排序。找范围。插入线段树,从线段树取出,查值。
排序的原因是我们在找范围的时候能让范围是连续变化的。线段树的pos就相当于一个媒介,
线段树的pos是真实高度哦!!!
此题看着很难,仔细分析下就好了。