bzoj1099

来源:互联网 发布:应用备份软件 编辑:程序博客网 时间:2024/06/05 19:23

此题代码很长待我闲的蛋疼的时候再来写。。。。

思路:

首先我们考虑一个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是真实高度哦!!!

此题看着很难,仔细分析下就好了。