题解:
显然对整个序列考虑不行,不如对每一个元素单独考虑。
一个元素x在x和x+1都成为分割点前显然会被一直计算答案,设(T(x))表示x分割点出现的时间。
那么(Ans=sum_{i=1}^n max(T(i-1),T(i)))。
众所周知,冒泡排序都是去考虑每一个元素的往左移动,而不是往右移动。
对冒泡排序的一个元素(a[i]),若它前面有(k)个比他大的数,那么前(k)轮它都会往前移动一格。
对于这题,只要(1..x)的元素全部退到(x)以前,就有(x)这个分割点了。
所以设(b[i])为(i)大的元素所在的位置,(T(x)=max(b[i]-x)(iin[1,x]))
这题有相同的元素,由于冒泡排序是稳定排序,所以相同的元素就考虑它们原来的位置就好了。
Code:
#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
#define ff(i, x, y) for(int i = x, _b = y; i < _b; i ++)
#define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
#define ll long long
#define pp printf
#define hh pp("
")
using namespace std;
const int N = 1e5 + 5;
int n, a[N], b[N], mx;
ll ans;
int cmpb(int x, int y) {
if(a[x] == a[y]) return x < y;
return a[x] < a[y];
}
int main() {
scanf("%d", &n);
fo(i, 1, n) scanf("%d", &a[i]), b[i] = i;
sort(b + 1, b + n + 1, cmpb);
int t1 = 0, t2;
fo(i, 1, n) {
mx = max(mx, b[i]);
t2 = max(mx - i, 1);
ans += max(t1, t2); t1 = t2;
}
pp("%lld
", ans);
}