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

浙公网安备 33010602011771号