luogu二分刷题

最近哈,最近发现有一点点怯题,,就是一做题就怕错,,,,,,战胜困难的最好的办法就是面对他!!!刷题走起!还是最容易抠细节的二分~~

有一个范围,并且数据比较大,并且有递增递减关系,,,,二分
注意!一般得开long long

//二分模板
while(left<=right){
		int mid=(left+right)>>1;
		tmp=0;
		for(int i=1;i<=n;i++) 
		    if(high[i]>mid) tmp+=high[i]-mid;
		if(tmp<m)
                    right=mid-1;
		else left=mid+1;
	}

还有一个是STL给出的upper_bound(>)和lower_bound(>=)
也是一个二分
p2249
**lower_bound和upper_bound别忘了减那个初值

#include<algorithm>
#include <vector>
#include <iostream>
using namespace std;
vector<int> ans;
int m,n;
int main(){
    cin>>m>>n;
    for (int i = 0; i < m; ++i) {
        int q;
        cin>>q;
        ans.push_back(q);
        //cout<<ans[i];
    }
    while(n--){
        int t;
        cin>>t;
        //cout<<t<<endl;
        int index=lower_bound(ans.begin(),ans.end(),t)-ans.begin();
        if(t==ans[index]){
           // cout<<t<<endl;
            cout<<index+1;
            //cout<<ans[index]<<endl;
        } else{
            cout<<"-1";
        }
        if(n){
            cout<<" ";
        }
    }
}

p1102

这个也没二分啊,直接map

#include<algorithm>
#include <vector>
#include <map>
#include <iostream>
typedef  long long  LL;
using namespace std;
map<LL,LL> mmp;
vector<LL> v;
LL ans=0;
int main(){
    LL m,c;
    cin>>m>>c;
    for (LL i = 0; i < m; ++i) {
        LL q;
        cin>>q;
        v.push_back(q);
        mmp[v[i]]++;
        v[i]-=c;
    }
    for (int i = 0; i < m; ++i) {
        ans+=mmp[v[i]];

    }
    cout<<ans<<endl;
    return 0;

}

p1873

二分模板题

#include<algorithm>
#include <vector>
#include <map>
#include <iostream>
typedef  long long  LL;
using namespace std;
//手算二分,怕怕
LL m,n;
vector<LL> v;
int main(){
    cin>>m>>n;
    for (LL i = 0; i < m; ++i) {
        LL t;cin>>t;
        v.push_back(t);
    }
    sort(v.begin(),v.end());
    LL l=v[0];

    LL r=v[m-1];
    LL mid;
    LL temp;
    while(l<=r){
        mid=(l+r)>>1;
        //cout<<"mid:"<<mid<<endl;
        temp=0;
        for (LL i = 0; i < m; ++i) {
            if(v[i]>mid){
                temp+=(v[i]-mid);
                //cout<<"v[i]-mid:"<<v[i]-mid<<endl;
            }

            //cout<<"temp"<<temp<<endl;
        }
        if(temp<n){
            r=mid-1;
        }
        else {
            l=mid+1;
        }

    }
    cout<<r;//上面的判断是搭配相等,while(<=),也就是说相等的时候底下的r和L也一直在变
}
#include<iostream> 

using namespace std;

long long L,N,M,d[50005],ans;

bool check(long long mid)
{
	int temp=0,now=0;
	for(int i=1;i<=N;i++)
	    if(d[i]-d[now]<mid) 
               temp++;
	    else now=i;
	if(temp>M)  return false;
	return true;
}

int main()
{
	cin>>L>>N>>M;
	for(int i=1;i<=N;i++)  cin>>d[i]; 
	
	int l=0,r=L;
	while(l<=r)
	{
		long long mid=(l+r)>>1;
		if(check(mid))  ans=mid,l=mid+1;
		else r=mid-1;
	}
	
	cout<<ans<<endl;//输出
	
	return 0;
}

posted @ 2021-01-31 21:12  安之若醇  阅读(53)  评论(0编辑  收藏  举报
Live2D服务支持