1. 程式人生 > >Codeforces 847 B. Preparing for Merge Sort (二分)

Codeforces 847 B. Preparing for Merge Sort (二分)

Description

Ivan has an array consisting of n different integers. He decided to reorder all elements in increasing order. Ivan loves merge sort so he decided to represent his array with one or several increasing sequences which he then plans to merge into one sorted array.

Ivan represent his array with increasing sequences with help of the following algorithm.

While there is at least one unused number in array Ivan repeats the following procedure:

iterate through array from the left to the right;

Ivan only looks at unused numbers on current iteration;

if current number is the first unused number on this iteration or this number is greater than previous unused number on current iteration, then Ivan marks the number as used and writes it down.

For example, if Ivan’s array looks like [1, 3, 2, 5, 4] then he will perform two iterations. On first iteration Ivan will use and write numbers [1, 3, 5], and on second one — [2, 4].

Write a program which helps Ivan and finds representation of the given array with one or several increasing sequences in accordance with algorithm described above.

Input

The first line contains a single integer n (1 ≤ n ≤ 2·10^5) — the number of elements in Ivan’s array.

The second line contains a sequence consisting of distinct integers a1, a2, …, an (1 ≤ ai ≤ 10^9) — Ivan’s array.

Output

Print representation of the given array in the form of one or more increasing sequences in accordance with the algorithm described above. Each sequence must be printed on a new line.

Examples input

5
1 3 2 5 4

Examples output

1 3 5
2 4

題意

找出所有不重疊不下降的子序列。

思路

有一種暴力的想法:我們可以在 O(n) 的時間複雜度找出當前陣列中的一個不下降子序列,然後從陣列中刪掉這部分繼續重複剛才的操作。

不過這佯的方法時間複雜度為 O(n2) ,顯然會超時。

考慮用佇列來儲存所有不重疊不下降的子序列,對於已拓展出的 len 個佇列,顯然其尾部數字的大小是按降序排列的。

比如我們有 5,4,3,2,1,6,8,7,5 這些數字,其在佇列中的儲存如下:

5,6,8
4,7
3,5
2
1

此時由所有佇列尾部組成的序列為 8,7,5,2,1 ,對於即將加入的新數字 x ,如果在已有佇列尾部可以找到一個編號最小且尾部小於等於 x 的索引,那麼我們可以將 x 加入到該佇列尾部,否則用它來拓展一個新佇列。

查詢採用二分總時間複雜度為 O(n×logn)

AC 程式碼

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5+10;
typedef __int64 LL;

LL a[maxn];
int n;
deque<LL> top[maxn];

int lower_update(int len,LL x)      // 找一個編號最小且佇列末尾元素小於 x 的索引
{
    int low = 0,high = len;
    while(low<high)
    {
        int mid = (low+high)>>1;
        if(*top[mid].rbegin()<=x)
            high = mid;
        else
            low = mid + 1;
    }
    if(high == len)return -1;
    return high;
}

void solve()
{
    int len = 0;
    for(int i=0; i<n; i++)
    {
        int res = lower_update(len,a[i]);   // 二分查詢
        if(res == -1)                       // 沒找到說明當前元素的值偏小
            top[len++].push_back(a[i]);
        else
            top[res].push_back(a[i]);
    }
    for(int i=0; i<len; i++)
    {
        cout<<top[i].front();
        top[i].pop_front();
        while(!top[i].empty())
        {
            cout<<" "<<top[i].front();
            top[i].pop_front();
        }
        cout<<endl;
    }
}

int main()
{
    cin>>n;
    for(int i=0; i<n; i++)
        cin>>a[i];
    solve();
    return 0;
}

相關推薦

Codeforces 847 B. Preparing for Merge Sort 二分

Description Ivan has an array consisting of n different integers. He decided to reorder all eleme

B. Preparing for Merge Sort(二分)

2017-2018 ACM-ICPC, NEERC, Southern Subregional Contest, qualification stage (Online Mirror, ACM-ICPC Rules, Teams Preferred) B. P

Preparing for Merge Sort CodeForces - 847B 二分

Ivan has an array consisting of n different integers. He decided to reorder all elements in increasing order. Ivan loves merge sort so he de

Codeforces 847B - Preparing for Merge Sort

break vector ons n) sync || efi cto syn 847B - Preparing for Merge Sort 思路:前面的排序的最後一個一定大於後面的排序的最後一個。所以判斷要不要開始新的排序只要拿當前值和上一個排序最後一個比較就可以了。

Codeforces 847B Preparing for Merge Sort

題目連結 題目大意: 給出一種n個不同數字的全排列,把他分割成多段嚴格遞增的子序列,並輸出分割後的序列. 例如1 4 2 3 5 6 按照遞增 分為 1 2 3 5 6和4 題目分析:因為n有2*1e5那麼大,所以暴力n^2明顯不行了,不過可以在暴力的基礎上通過二分查詢使時

Preparing for Merge SortCodeForces

 這真的是一道很不錯的題,告誡了我很多時候遇到上升序的題,要去擅於使用二分來解決問題,尤其是這次的lower_bound(),說實話,我還真的不是擅長寫lower_bound(),這次的題算是給我漲了個教訓吧。 Ivan has an array consisting of

CodeForces 817 B.Makes And The Product水~

Description 給出n個正整數ai,問有多少三元組(i,j,k)滿足1≤i<j<k≤n且ai⋅aj⋅ak最小 Input 第一行一整數n表示序列長度,之後輸入n個整數ai(3≤

HDU 6119 2017百度之星初賽B 小小粉絲度度熊 二分

端點 mission make miss 情況 others sin time 天都 小小粉絲度度熊 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To

codeforces#439 D. Devu and his Brother 二分

最大 sca sha main cout 修改 ace \n 最小值 題意:給出a數組和b數組,他們的長度最大1e5,元素範圍是1到1e9,問你讓a數組最小的數比b數組最大的數要大需要的最少改變次數是多少。每次改變可以讓一個數加一或減一 分析:枚舉a數組和b數組的所有的元

Educational Codeforces Round 50 (Rated for Div. 2).B. Diagonal Walking v.2思維

B. Diagonal Walking v.2 time limit per test 1 second memory limit per test 256 megabytes input standard input output standard outp

Educational Codeforces Round 58 (Rated for Div. 2)B. Accordion

B. Accordion time limit per test3 seconds memory limit per test256 megabytes inputstandard input

HDU1867 A + B for you againKMP

字典 不一定 string 連接 title pan log cst tail A + B for you again Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/O

【思維】Codeforces Round #485 (Div. 2) B. High School: Become Human對數

space scanf CA ace ima AC bsp ont http 題目鏈接:http://codeforces.com/contest/987/problem/B 在運算的時候取對數就好了 1 #include <bits/stdc++

Codeforces】CF 2 B The least round waydp

clu 更新 .org ORC 我們 std 預處理 blank putc 題目 傳送門:QWQ 分析 求結尾0的數量QwQ。 10只能是$ 2 \times 5 $,我們預處理出每個數因子中2和5的數量。 我們接著dp出從左上到右下的經過的最少的

CodeForces 129 B】Students and Shoelaces拓撲排序

end owin clu namespace 每次 font order 單獨 when Anna and Maria are in charge of the math club for junior students. When the club gathers tog

codeforces 962D. Merge EqualsSTL

                                                                                                D. Merge Equals time limit per test 2 se

CodeForces B. The least round waydp

B. The least round way time limit per test 5 seconds memory limit per test 64 megabytes input standard input output standard output Th

排序算法系列:歸併排序(Merge sort)C語言

通俗理解:運用分而治之的思想,編寫遞迴函式,將大陣列排序轉化為小陣列排序,最後再將其合併。void merge_sort(int*p,int low,int high) { int mid = (low+high)/2; if (low <high) { m

表的連線方式:NESTED LOOP、HASH JOIN、SORT MERGE JOIN修改

表連線方式及使用場合NESTED LOOP 巢狀迴圈連線        由兩個for迴圈組成。不管什麼連線,本演算法都可以使用。連線的兩個關係,分別稱之為外層關係和內層關係,把資料塊數大的關係作為外層關係,小的關係作內層關係。分為塊巢狀迴圈連線(簡單點說,就是把已經放在記

Educational Codeforces Round 57 (Rated for Div. 2) 待更新

A.Find Divisible You are given a range of positive integers from l to r . Find such a pair of integers (x,y) that l≤x,y≤r , x≠y and x divides y .