码迷,mamicode.com
首页 > 其他好文 > 详细

Preparing for Merge Sort(二分)

时间:2020-05-05 20:27:48      阅读:63      评论:0      收藏:0      [点我收藏+]

标签:pos   组队   ack   name   惊奇   mes   using   stdin   com   

Preparing for Merge Sort

思路

手动模拟样例一后惊奇的发现了一个规律

技术图片

这组样例一共有两个队列输出,我们发现任意时刻每组数据都满足一个条件,最末尾的数字是严格按照单调递减的顺序的。我们每一次添加数字的操作,都是从下向上寻找最后一个小于当前要添加数字的队列编号。

这一操作是不是很像\(lower\_bound - 1\)的操作,但是却是一个反向的\(lower\_bound - 1\),于是我又开了一个数组来反向存最后一个数字,假如原本的第一组数据的最后一个数字是1,我们在下标为\((n - 1)\)的数组上存储1,这样就可以实现我们的二分查找位置操作了。

再来说一下二分查找的细节。

假如我们的\(lower\_bound\)返回的是\(n\)下标,这说明我们没有找到比当前数字更大的数字,所以这里我们需要特判,将其添加到第一组队列数据当中去。

如果我们的\(lower_bound\)返回的是下标\(n - 1\)说明队列1末尾的最后一个数字比当前要添加的数字是更大的,所以我们需要添加到队列2当中去。

还有一点就是这里好像一定得用动态数组存答案,不然\(2e5 * 2e5\)会爆内存。

代码

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

vector<int> ans[N];
int a[N], n, m, b[N];

int main() {
    // freopen("in.txt", "r", stdin);
    int t;
    scanf("%d", &n);
    for(int i = 0; i < n; i++) {
        scanf("%d", &t);
        int pos = lower_bound(b, b + n, t) - b;
        if(pos == n) {
            b[n - 1] = t;
            a[0] = t;
            ans[0].push_back(t);
        }
        else {
            b[pos - 1] = t;
            a[n - pos] = t;
            ans[n - pos].push_back(t);
        }
    }
    for(int i = 0; a[i]; i++) {
        for(int j = 0; j < ans[i].size(); j++)
            printf("%d ", ans[i][j]);
        puts("");
    }
    return 0;
}

Preparing for Merge Sort(二分)

标签:pos   组队   ack   name   惊奇   mes   using   stdin   com   

原文地址:https://www.cnblogs.com/lifehappiness/p/12831801.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!