二分学习笔记

二分学习笔记


前几天做的那个后缀数组,发现我的二分完全是凉的。主要是一些边界上的问题,于是在这里重新把常用的二分写一遍。下面这几个应该是没有问题的,如果有童鞋发现了不正确的地方,麻烦评论区指出。

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

猜你喜欢

转载自www.cnblogs.com/RRRR-wys/p/9360047.html