题意:任意选择一个区间 [l, r],满足求区间中第i个位置不能是第i小的数,求符和要求的子区间个数
思路: 双指针+差分 枚举左端点,双指针求不满足要求的区间,用差分记录区间 [i,j] 内不合法点的数量,最后对答案进行统计即可 复杂度()
#include<bits/stdc++.h>
using namespace std;
const int N =1e6+10;
const int M =400+10;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int>PII;
#define pb push_back
#define int ll
//__builtin_popcountll(x) 二进制 1 个数
const ll mod = 998244353;
int n,m,k,r;
void solve(){
cin>>n;
vector<int>a(n+1);
vector<vector<int>> sum(n+2,vector<int>(n+2));
for(ll i=1;i<=n;i++) cin>>a[i];
ll ans = 0;
for(int i=1;i<=n;i++){
int l = i,r = i;
while(r<n&&a[r+1]>a[i]) r++;
sum[i][l]++;
sum[i][r+1]--;
for(int j = i-1;j>=1;j--){
if(a[j]>a[i]){
r++;
l = r;
while(r<n&&a[r+1]>a[i]) r++;
}
if(l<=n){
sum[j][l]++;
sum[j][r+1]--;
}
}
}
for(int i=1;i<=n;i++){
ll num = 0 ;
for(int j=i;j<=n;j++){
num+=sum[i][j];
if(num==0) ans++;
}
}
cout<<ans<<'\n';
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T=1;
cin>>T;
while(T--){
solve();
}
return 0;
}