二分学习笔记
二分学习笔记
前几天做的那个后缀数组,发现我的二分完全是凉的。主要是一些边界上的问题,于是在这里重新把常用的二分写一遍。下面这几个应该是没有问题的,如果有童鞋发现了不正确的地方,麻烦评论区指出。
#include <bits/stdc++.h>
const int N = 100010;
using namespace std;
bool cmp(int a,int b) {return a>b;}
int sc1(int a[],int n,int x) {
int l=1,r=n;
while(l<r) {int mid=(l+r)>>1;
if(a[mid]>=x)r=mid;
else l=mid+1;
}
if(a[l]<x)l=n+1;
return l;
}
int sc2(int a[],int n,int x) {
int l=1,r=n;
while(l<r) {int mid=(l+r)>>1;
if(a[mid]>x)r=mid;
else l=mid+1;
}
if(l==n&&a[n]<=x)l=n+1;
return l;
}
int sc3(int a[],int n,int x){
int ans=-1,l=1,r=n;
while(r-l>=0) {
int mid=(l+r)/2;
if(a[mid]<=x) {
ans=mid;
r=mid-1;
}
else l=mid+1;
}
return ans;
}
int sc4(int a[],int n,int x){
int ans=-1,l=1,r=n;
while(l<=r) {
int mid=(l+r)/2;
if(a[mid]<x) {
ans=mid;
r=mid-1;
}
else l=mid+1;
}
return ans;
}
//下标由1开始
//1递增序列第一个大于等于x的数,不存在输出n+1
//2递增序列第一个大于x的数,不存在输出n+1
//3递减序列第一个小于等于x的数,不存在输出-1
//4递减序列第一个小于x的数,不存在输出-1
int n,q,a[N],b[N],x,opt;
int main() {
while(scanf("%d%d",&n,&q)!=EOF) {
for(int i=1;i<=n;++i)scanf("%d",&a[i]);
sort(a+1,a+1+n);
for(int i=1;i<=n;++i) b[n-i+1]=a[i];
while(q--) {
scanf("%d%d",&opt,&x);
switch (opt){
case 1: printf("%d\n",sc1(a,n,x));break;
case 2: printf("%d\n",sc2(a,n,x));break;
case 3: printf("%d\n",sc3(b,n,x));break;
case 4: printf("%d\n",sc4(b,n,x));break;
}
}
}
return 0;
}