题解 CF1557B 【Moamen and k-subarrays】
CF1557B Moamen and k-subarrays
题目大意:
给定一个大小为 \(n\) 的数组。你可以将其分为 \(k\) 个子数组,并按照每个子数组的字典序重新排列这些子数组,再顺次拼接,得到一个新的数组。问是否存在一种划分子数组的方案,使得重新拼接后的数组是单调不降的?
solution:
我们可以先将原数组排好序,用有序的数组与原数组比较。我们发现,两个可以在一个子数组里的数在有序数组里一定是相邻的。所以我们检查原数组,看 \(a_i\) 与 \(a_{i+1}\) 是否是相邻的即可,用一个类似离散化的写法。
代码
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=3e5+5;
int a[N],c[N];
struct node{
int x,w;
}b[N];
inline bool cmp(node p,node q){ return p.w<q.w; }
int main(){
int T; scanf("%d",&T);
while(T--){
int n,k; scanf("%d%d",&n,&k);
int ans=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
b[i].w=a[i];//保存大小,用来排序
b[i].x=i;//保存位置
}
sort(b+1,b+n+1,cmp);//排序
for(int i=1;i<=n;i++){
a[b[i].x]=i;//将这个数标记成第 i
}
for(int i=1;i<n;i++){
if(a[i]==a[i+1]-1);//看与它右面的数是不是相邻的
else ans++;//否则需要分的组数++
}
if(ans>=k) puts("No");//这里 ans其实应该从 1 开始,我这里是0,所以是≥
else puts("Yes");
}
return 0;
}