[TJOI2016]排序——[线段树]

在这里插入图片描述
【题意分析】

首先,暴力sort有30pts…

全排列是一个特别好的性质,我们想想有没有特别的做法。

由于数字保证不重复,对于x,把大于等于x的数全部变为1,把小于x的数全部变成0。

那么我们可以发现:对于要排序的区间[l,r],如果是升序,那么区间前面肯定是若干个零,后面全是1,如果是降序,那么区间前面全都是1, 后面全都是0。

然后这样操作之后我们看看要求的q位置上数字是否为1,就可以初步确定排完后这个位置上的数比x大还是比x小。(1是比x大,0是比x小)

想到什么?二分这个x,二分到最后无法再放缩时,说明我们已经找到了答案。

现在唯一的问题就是排序,由于序列全是0和1,我们可以考虑用线段树维护:利用线段树可以求出每段区间有几个0与几个1(区间求和就可以算出几个1),排序时,只要一段一段地赋值即可。

具体操作:对于区间 [ l , r ] [l,r] [l,r]有res个1,那么如果是降序, [ l , l + r e s − 1 ] [l,l+res-1] [l,l+res1]为1, [ l + r e s , r ] [l+res,r] [l+res,r]为0.
如果是升序, [ l , r − r e s ] [l,r-res] [l,rres]为0, [ r − r e s + 1 , r ] [r-res+1,r] [rres+1,r]为1

Code :

#include <iostream>
#include <cstdio>
#
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值