Sleepy Cow Sorting G
题目描述
题目分析
对于一个连续递增的长度为k
的后缀来说,它们是不需要移动的,所以移动的次数为n-k
。而x
每次移动的距离应该为其到后缀的距离加上此后缀中比x
小的数的个数cnt
。
由于后缀是在变化的则cnt
也会相应的产生变化,为此我们需要一个数据结构来维护后缀,可以使用树状数组进行维护。
先将后缀中的数字后加入到树状数组中,每移动一个数字就更新一次树状数组,相应的赋值为1,此后缀中比x
小的数的个数cnt = sum(x-1)
。
code
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 10;
int n, m, k, t;
int tr[N], a[N];
int lowbit(int x)
{
return x & (-x);
}
void add(int x, int c)
{
for(int i = x; i <= n; i += lowbit(i)) tr[i] += c;
}
int sum(int x)
{
int res = 0;
for(int i = x; i; i -= lowbit(i)) res += tr[i];
return res;
}
signed main()
{
cin >> n;
for(int i = 1; i <= n; i ++) cin >> a[i];
int res = n, k = 0;
while(a[n - k] > a[n - k - 1])
{
add(a[n - k], 1);
k ++, res --;
}
add(a[n - k], 1), res --;
cout << res << "\n";
for(int i = 1; i <= res; i ++)
{
add(a[i], 1);
cout << res - i + sum(a[i] - 1) << " ";
}
return 0;
}