题解:CF2124D Make a Palindrome
首先,由于只需要满足区间长度
但是注意:排名刚好为
因为其中只有一部分可以被删除,而我们不能直接知道是哪些。
接着我们考虑删除哪些位置。一个经典的做法是回文串从两头向中间匹配。我们碰到匹配成功的直接跳过,缩减
- 有一个指针处的数的排名为
k ,那么直接删除它,并记录删除次数。 - 若两个指针处的数排名均不为
k ,那么直接结束,无解。
最后判断一下删除次数是否合法即可。
#include<bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
#define e_b emplace_back
#define p_b push_back
#define fir first
#define sec second
#define gc getchar
#define ios ios::sync_with_stdio(0),cin.tie(0)
using namespace std;
const int N=2e5+5,mod=1e9+7,inf=1e9;
int n,k,a[N],b[N];
int c[N];
void solve(){
cin>>n>>k;
for(int i=1;i<=n;i++)cin>>a[i],b[i]=a[i];
sort(b+1,b+n+1);
int m=0;
for(int i=1;i<=n;i++){
int rk=lower_bound(b+1,b+n+1,a[i])-b;
if(rk<=k)c[++m]=a[i];
}
int l=1,r=m,tt=m-k+1;
while(1){
//cout<<l<<' '<<r<<'\n';
if(l>=r)break;
if(c[l]!=c[r]){
if(c[l]==b[k])l++,tt--;
else if(c[r]==b[k])r--,tt--;
else{cout<<"No\n";return;}
}
else l++,r--;
if(tt<0){cout<<"No\n";return;}
}cout<<"Yes\n";
}
signed main(){
ios;int T;cin>>T;
while(T--)solve();
}