Loading

Solution for ABC478C

我们需要找到一个长度为 \(k\) 的区间,这个区间是无序的,并且将这个区间进行排序后,其他位置都是有序的。

那么意思就是,在这个 \(a\) 数组中,连续的无序部分的长度是不超过 \(k\) 的,只要找到这个 \(a\) 数组中连续无序的部分,然后进行模拟这个过程,最后检查一下 \(a\) 数组是否有序就行了。

具体的:

我们需要找到这个连续无序的区间,即为找到这个无序区间的左端点和右端点,设为 \(l,r\)。如果说区间长度超过了 \(k\),即为 \(r-l+1>k\),是一定无法进行操作从而得到升序的,可以进行特判。(其实不用,因为一般解法可以覆盖这个情况)

那么整个 \(a\) 数组就被分为了 3 个部分,分别是 \([1,l-1],[l,r],[r+1,n]\),其中 \([l,r]\) 是无序区间。我们需要覆盖整个无序区间从而进行排序。因为需要覆盖整个无序区间,那么问题就变成了将 \([l,l+k-1]\) 或者 \([r-k+1,r]\) 进行排序,是否能让整个 \(a\) 数组形成升序。

Code
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
int n,k,a[N],tmp[N];
int check(int id){
    if(id<1||id>n) return 0;
    for(int i=1;i<=n;i++) tmp[i]=a[i];
    sort(tmp+id,tmp+id+k);
    for(int i=2;i<=n;i++){
        if(tmp[i]<tmp[i-1]){
            return 0;
        }
    }
    return 1;
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    cin>>n>>k;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        tmp[i]=a[i];
    }
    sort(tmp+1,tmp+1+n);
    int l=0,r=0;
    for(int i=1;i<=n;i++){
        if(a[i]!=tmp[i]){
            if(l==0) l=i;
            r=i;
        }
    }
    if(!l){
        cout<<"Yes"<<'\n';
        return 0;
    }
    if(check(l)||check(r-k+1)) cout<<"Yes"<<'\n';
    else cout<<"No"<<'\n';
    return 0;
}

Submission

posted @ 2026-10-04 09:24  AddFlowers  阅读(4)  评论(0)    收藏  举报