1 条题解

  • 0
    @ 2026-8-2 15:24:29

    显然,因为操作之间可以覆盖,而尽可能大的数需要尽可能长的铺垫(对于 aia_i 需要满足前面至少有 aia_i 个位置),所以操作时应当是从后往前操作。

    又显然,每一次操作后的 XX 序列的每一个数都只会增加,而不会减少。

    比如下面这组:

    0 1 1 0 1 2 2 2 3
    

    我们先去操作最后一个三,这样后 XX 就会变成这样

    0 0 0 0 0 0 1 2 3
    

    此时我们考察倒数第二个数,可以发现不论再怎么操作,你都不能把它变成更小的数。

    所以另一种无解的情况就是存在一个 ii,使得存在 jj 满足 (ij)ai(i-j)\le a_iaj<ai(ij)a_j<a_i-(i-j)

    判完无解之后,我们对于每一个 ii,从后往前扫,如果扫到的 jj 满足 aj=ai(ij)a_j=a_i-(i-j),说明这个 jj 在我们操作 ii 时就已经会变成相应的 aja_j 了,不需要再去操作。如果大于,那么我们就把它当成一个新的起点,重新开始扫就行。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    int a[200005];
    int main(){
    	int n;
    	cin>>n;
    	for(int i=1;i<=n;i++){
    		cin>>a[i];
    		if(a[i]>i-1){
    			cout<<-1;
    			return 0;
    		}
    	}
    	long long ans=0;
    	for(int i=n;i>1;i--){
    		ans+=a[i];
    		int j=i-1;
    		while(a[j]==a[i]-(i-j)){
    			j--;
    		}
    		if(a[j]<a[i]-(i-j)){
    			cout<<-1;
    			return 0;;
    		}
    		else{
    			i=j+1;
    		}
    	}
    	cout<<ans;
    	return 0;
    }
    
    • 1

    信息

    ID
    8665
    时间
    2000ms
    内存
    1024MiB
    难度
    10
    标签
    递交数
    5
    已通过
    2
    上传者