Non-Puzzle: Error Permutation

题意:任意选择一个区间 [l, r],满足求区间中第i个位置不能是第i小的数,求符和要求的子区间个数

思路: 双指针+差分 枚举左端点,双指针求不满足要求的区间,用差分记录区间 [i,j] 内不合法点的数量,最后对答案进行统计即可 复杂度(n^2

#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值