【題意分析】
首先,暴力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+re
s−1]
[l,l+res-1]
[l,l+r
es−1
]為1,[l+
res,
r][l+res,r]
[l+res
,r]為0.
如果是公升序,[l,
r−re
s][l,r-res]
[l,r−r
es]為0,[r−
res+
1,r]
[r-res+1,r]
[r−res
+1,r
]為1code :
#include
#include
#include
#include
#include
#include
#define maxn 200000
using
namespace std;
struct node ques[maxn]
;int tree[maxn <<2]
, lazy[maxn <<2]
, a[maxn]
, b[maxn]
, n, q, res, pos, ans;
inline
int read (
)while
(isdigit (ch)
)return s * w;
}inline
void pushup (
int now)
inline
void pushdown (
int now,
int l,
int r)
void build (
int now,
int l,
int r)
int mid = l + r >>1;
build (now <<
1, l, mid)
; build (now <<1|
1, mid +
1, r)
; pushup (now);}
void update (
int now,
int l,
int r,
int l,
int r,
int k)
if(lazy[now]!=-
1) pushdown (now, l, r)
;int mid = l + r >>1;
update (now <<
1, l, mid, l, r, k)
; update (now <<1|
1, mid +
1, r, l, r, k)
; pushup (now);}
void query (
int now,
int l,
int r,
int l,
int r)
if(lazy[now]!=-
1) pushdown (now, l, r)
;int mid = l + r >>1;
query (now <<
1, l, mid, l, r)
; query (now <<1|
1, mid +
1, r, l, r);}
inline
bool check (
int x)
else
} res =
0, query (1,
1, n, pos, pos)
;return res;
}int main (
)return printf (
"%d\n"
, ans),0
;}
09 排序1 排序
09 排序1 排序 25 分 給定n 個 長整型範圍內的 整數,要求輸出從小到大排序後的結果。本題旨在測試各種不同的排序演算法在各種資料情況下的表現。各組測試資料特點如下 include include includeusing namespace std const int cutoff 1000...
09 排序1 排序
n個 長整型範圍內的 整數,要求輸出從小到大排序後的結果。資料2 11個不相同的整數,測試基本正確性 資料3 10 3個隨機整數 資料4 10 4個隨機整數 資料5 10 5個隨機整數 資料6 10 5個順序整數 資料7 10 5個逆序整數 資料8 10 5個基本有序的整數 資料9 10 5個隨機正...
09 排序1 排序
本題旨在測試各種不同的排序演算法在各種資料情況下的表現。各組測試資料特點如下 資料1 只有1個元素 資料2 11個不相同的整數,測試基本正確性 資料3 103個隨機整數 資料4 104個隨機整數 資料5 105個隨機整數 資料6 105個順序整數 資料7 105個逆序整數 資料8 105個基本有序的...