Range Sorting (Easy Version)
题意:
给出一个数组,对所有子数组,找到其中的非升序区间r,l。其花费为r - l。求数组a的总花费。
思路:
先初始化答案,即对于每个i,ans += (i - 1) * ((i - 1) + 1) / 2。
即等差数列求和,把所有合法不合法的花费都加起来,后面再把合法的减去。合法即升序,不合法为非升序。
随后对于每个位置i,找到它前面的合法区间和后面的合法区间,ans减去前面的合法区间*后面的合法区间。
具体看代码。
代码:
/*************************************************************************
> File Name: d1.cpp
> Author: Beans
> Mail: 3112748286@qq.com
> Created Time: 2023/5/15 10:48:36
************************************************************************/
#include <iostream>
#include <algorithm>
#include <vector>
#define int long long
#define endl '\n'
using namespace std;
const int maxn = 5e3 + 7;
int t, n, a[maxn];
void solve(){
cin >> n;
int ans = 0;
for(int i = 1; i <= n; i ++ ) cin >> a[i], ans += (i - 1) * ((i - 1) + 1) / 2;
for(int i = 1; i <= n; i ++ ){
int k = i;
while(k >= 1 && a[k] >= a[i]) k -- ;
int x = k;
if(k >= 1) while(x >= 1 && a[x] <= a[i]) x -- ;
int y = i;
while(y <= n && a[y] >= a[i]) y ++ ;
ans -= (k - x) * (y - i);
}
cout << ans << endl;
}
signed main(){
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> t;
while(t -- )
solve();
}