题意
给你一个大小为n的数组,让你找出里面的顺序对并且输出出来。
思路
最开始我想的是用树状数组,因为想到了树状数组求逆序对,那么树状数组肯定是可以求顺序对的,但是有一个问题是,用树状数组只能找到顺序对的个数,并不能将它输出出来(应该可以吧,反正我不会)。
所以换了一个思路,我们每一次输出,都是输出顺序的,那么对于这一组数中,每一个数都是大于它前面那个数的第一个位置,所以想到了用二分的方法,我们每一次寻找大于这个数的第一个位置,然后将这个数加入到一个vector中,并且将这个位置的数替换成当前这个数。如图:(我们用测试样例:1 3 2 5 4)
代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 10;
int n;
int a[N];
vector<int> vec[N];
int lo_bound(int x)
{
int l = 0, r = n;
while (l < r)
{
int mid = l + r + 1 >> 1;
if (a[mid] <= x) l = mid;
else r = mid - 1;
}
return l;
}
void solve()
{
cin >> n;
for (int i = 0; i < n; i ++)
{
int x; cin >> x;
int cur = lo_bound(x);
a[cur] = x;
vec[cur].push_back(x);
}
for (int i = n; i >= 0; i --)
{
int len = vec[i].size();
if (len)
{
for (int j = 0; j < len; j ++) cout << vec[i][j] << ' ';
cout << endl;
}
}
}
signed main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
solve();
return 0;
}