题目的意思是给定一个数组,求有多少个子数组满足子数组可以恰好分为若干个"块"
用len[i]表示从i到前面有多少个连续的数等于a[i],例如a[] = {1,1,2,2,2,1},那么len[] = {1,2,1,2,3,1}
显然初始化len[] = {1,1,1,1,1,1},从i  2开始,如果a[i] = a[i - 1],那么len[i] = len[i - 1] + 1
for(int i = 2; i <= n; i ++){
    if(a[i] == a[i - 1]) len[i] = len[i - 1] + 1;
}
然后定义dp[i]表示以i位置结尾的所有子数组中满足条件的子数组个数
第i个位置的数为a[i],那么前面a[i]个数字必须为a[i],那么dp[i] = 1 + dp[i - a[i]];如果不满足,那么dp[i] = 0,表示以i位置结尾的所有子数组中没有满足条件的子数组
for(int i = 1; i <= n; i ++){
    if(i - a[i] + 1 >= 1 && len[i] >= a[i]) dp[i] = 1 + dp[i - a[i]];
    else dp[i] = 0;
    ans += dp[i];
}
总代码:
#include<bits/stdc++.h>
using namespace std;

#define endl '\n'
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define HelloWorld IOS;



void solve(){
    int n; cin >> n;
    vector<int> a(n + 1), len(n + 1, 1);
    for(int i = 1; i <= n; i ++) cin >> a[i];
    for(int i = 2; i <= n; i ++){
        if(a[i] == a[i - 1]) len[i] = len[i - 1] + 1;
    }

    vector<int> dp(n + 5, 0);
    int ans = 0;
    for(int i = 1; i <= n; i ++){
        if(i - a[i] + 1 >= 1 && len[i] >= a[i]) dp[i] = 1 + dp[i - a[i]];
        else dp[i] = 0;
        ans += dp[i];
    }
    cout << ans << endl;
    return ;
}
signed main(){
    HelloWorld;
    
    int tt; cin >> tt;
    while(tt --) solve();
    return 0; 
}