codeforces刷题日记
题目大意:给你一个1-n的随机排列p,现在用题目给你的二分算法,要求最多交换两次p中的两个元素后,对p使用二分算法得出的l对应值为x。输出交换次数和交换位置i,j
思路:先直接上结论,对p直接使用二分,最终如果l的值对应x那我们就输出0即可,那如果l对应位置元素不是x,那需要交换的元素就是p[l]和x。为什么这样是正确的,首先我们看二分的逻辑只有当p[m]<=x时才会将l指针移动到m上,意味着最终l对应的元素一定是<=x的,而我们二分移动r和l的判断依据就是是否<=x,x和p[l]都是<=x的,所以不会改变原来二分的流程,即我们将l位置上元素和x交换,如果重新二分,和原来直接对p二分,对应l位置一样。
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
int p[maxn],n,x,t;int posx;
int main(){
cin>>t;
while(t--){
cin>>n>>x;
for(int i=1;i<=n;i++){
cin>>p[i];
if(p[i]==x) posx=i;
}
int l=1,r=n+1;
while(l+1!=r){
int m=r+l>>1;
if(p[m]<=x) l=m;
else r=m;
}
if(p[l]==x) cout<<0<<endl;
else {
cout<<1<<endl;
cout<<l<<" "<<posx<<endl;
}
}
return 0;
}