兩種搜索二分模板

最小滿足

模板:

int l=min_num,r=max_num,ans=0;
while(l<=r){
	int m=(l+r)/2;
	if(isok(m)) {
		ans=m;
		r=m-1;
	}
	else 
		l=m+1;
}
cout<<ans<<endl;

例題:CF570C. Computer Game

#include<bits/stdc++.h>
using namespace std;
int n,a,b,k;
bool judge(int mb){
	int ma=n-mb;
	if(k-1ll*(ma-1)*a>a&&1ll*ma*a+1ll*mb*b<k) return true;
	else return false;
}
void solve(){
	cin>>k>>n>>a>>b;
	if((k-1)/b<n) {
		cout<<"-1"<<endl;
		return ;
	}
	int mb=n;
	int l=0,r=n,ans=0;
	while(l<=r){
		int m=(l+r)/2;
		if(judge(m)) {
			ans=max(ans,n-m);
			r=m-1;
		}
		else l=m+1; 
	}
	cout<<ans<<endl;
	return ;
}
int main(){
	int T;cin>>T;
	while(T--){
		solve();
	}
}


最小不滿足

模板:

int l=min_num,r=max_num;
while(l<r){
	int m=(l+r)/2;
	if(isok(m)) l=m+1;
	else r=m;
}
cout<<l<<endl;

例題:P1083 借教室

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int c[maxn];
int a[maxn],l[maxn],r[maxn];
int b[maxn];
int n,m,ll,rr,mid;
bool judge(int t){
    long long sum=0;
    memset(c,0,sizeof c);
    for(int i=1;i<=t;++i){
        c[ l[i] ]+=a[i];
        c[r[i]+1]-=a[i];
    }
    for(int i=1;i<=n;++i){
        sum+=c[i];
        if(sum>b[i]) {
                return false;
        }
    }
    return true;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        scanf("%d",&b[i]);
    }
    for(int i=1;i<=m;++i){
        scanf("%d%d%d",&a[i],&l[i],&r[i]);
    }
    if(judge(m)){
        printf("0");
        return 0;
    }
    ll=1,rr=m,mid=(ll+rr)/2;
    while(ll<rr){
    	mid=(ll+rr)/2;
        if(judge(mid)){
            ll=mid+1;
        }
        else {
            rr=mid;
        }
    }
    if(ll>=m)
        printf("0");
    else
        printf("-1\n%d",ll);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章