首页 > 其他分享 >[AcWing 789]数的范围

[AcWing 789]数的范围

时间:2022-11-10 11:58:23浏览次数:45  
标签:cin int mid 789 答案 AcWing check 模板 范围

image
image


点击查看代码
#include<iostream>
using namespace std;

const int N = 100010;
int n, m;
int q[N];

int main(){
    cin >> n >> m;
    for(int i = 0; i < n; i++) cin >> q[i];
    while(m--){
        int x;
        cin >> x;
        
        int l = 0, r = n-1;
        while(l < r){
            int mid = l+r >> 1;
            if(q[mid] >= x){
                r = mid;
            }
            else{
                l = mid + 1;
            }
        }//模板r = mid
        
        if(q[l] != x){
            cout << "-1 -1" << endl; //数组中不存在元素x
        }
        else{
            cout << l << ' '; //元素x的起始位置
            
            int l = 0, r = n-1;
            while(l < r){
                int mid = l+r+1 >> 1;
                if(q[mid] <= x){
                    l = mid;
                }
                else{
                    r = mid - 1;
                }
            }//模板l = mid
            
            cout << l << endl; //元素x的终止位置
        }
        
    }
    
    return 0;
} 


/*
整数二分:
本质并不是单调性
但与单调性的关系是:
如果有单调性则一定可以二分
但可以二分的题目不一定非得有单调性

本质是边界
找到一个性质
整个区间一分为二
左半边不满足性质 右半边满足性质
可以找到分界处的两个边界点
 对应两个模板

第一种情况:想二分左半边的边界点时
mid = (L+R+1) / 2      //加1是为了防止死循环
if(check(mid))
	情况 答案新区间    更新
	true    [mid,R]           L=mid
	false    [L,mid-1]        R=mid-1
模板:
//区间[L,R] 被划分成[L,mid-1]和[mid,R]时使用:
int bsearch_2(int l, int r){
	while(l < r){
		int mid = l+r+1 >> 1;
		if(check(mid)) l = mid;
		else r = mid-1;
	}
	return l;
}


第二种情况:想二分右半边的边界点时
mid = (L+R) / 2
if(check(mid))
	情况 答案新区间    更新
	true    [L,mid]           R=mid
	false    [mid+1,R]      L=mid+1
模板:
//区间[L,R] 被划分成[L,mid]和[mid+1,R]时使用:
int bsearch_1(int l, int r){
	while(l < r){
		int mid = l+r >> 1;
		if(check(mid)) r = mid;
		else l = mid+1;
	}
	return l;
}

二分的模板是一定要保证有解的
原本的题是可以无解的 二分不用考虑无解

方法:
先写一个mid 
随便先想一个check函数(想清楚性质)
根据check函数的值想一下答案是怎么去划分的
选择答案所在的区间
true 时答案在哪个边界里面
false时答案在哪个边界里面
更新时是L=mid还是R=mid
确定求mid处是否需要补上+1

*/


  1. 性质划分,确定答案所在区间,确定如何更新区间边界
  2. 两种情况:L=mid时mid=(l+r+1)/2; R=mid时mid=(l+r)/2
  3. 模板记忆

标签:cin,int,mid,789,答案,AcWing,check,模板,范围
From: https://www.cnblogs.com/starryWJ/p/16876570.html

相关文章

  • 【C#】C# 限制鼠标的移动范围
    publicstructRECT{publicintLeft;publicintTop;publicintRight;publicintBottom;......
  • PMP-产品范围与项目范围区别
    1、产品范围——某项产品、服务或成果所具有的特性和功能。2、项目范围——为交付具有规定特性与功能的产品、服务或成果而必须完成的工作。3、验收依据:根据项目管理计......
  • Pycharm 从外部范围隐藏名称xx的问题
      在接手一个Python项目的时候,通过Pycharm打开该项目,然后一片错误/警告之类的问题。为了能快速解决这些问题,我采取了一个比较笨的办法,就是重装了Python环境,并因此解决......
  • AcWing 896.最长上升子序列Ⅱ
    题目链接:http://www.acwing.com/problem/content/898/不像是dp,更像是贪心相对于数据小的上升子序列问题,此题用过的二分后的时间复杂度为nlogn。在本题中首先需要明白:......
  • 需求工程阅读笔记2之上下范围图
    在一个项目之初,首先要考虑的一个问题是:为什么要启动项目?也就是说项目的目标是什么。而第二个问题就是项目打算做什么,而上下文范围图将会清晰的展示一个项目的边界,初步展示......
  • AcWing 3583 整数分组(01背包 + 双指针)
    原题链接本题是比较明显的01背包,选或者不选,中间可以用双指针找到最后可以选到的区间长度,那么如果选当前最后一个区间的话最后就要求这个区间前面的长度要最大状态表示:f[......
  • 2022-11-08 Acwing每日一题
    本系列所有题目均为Acwing课的内容,发表博客既是为了学习总结,加深自己的印象,同时也是为了以后回过头来看时,不会感叹虚度光阴罢了,因此如果出现错误,欢迎大家能够指出错误,我......
  • ACWING 第 76 场周赛 ABC
    https://www.acwing.com/activity/content/2589/这场周赛也很简单,除了C我在赛场上写的时候有点小bug,赛时没改出来,哎,真废啊4713.反转字符串#include<bits/stdc++.h>u......
  • 2022-11-07 Acwing每日一题
    本系列所有题目均为Acwing课的内容,发表博客既是为了学习总结,加深自己的印象,同时也是为了以后回过头来看时,不会感叹虚度光阴罢了,因此如果出现错误,欢迎大家能够指出错误,我......
  • Java中Number下各数据类型的范围说明
    转自:http://www.java265.com/JavaCourse/202111/1792.html下文笔者将着重讲述java基础知识,Number类型包含的类型简介说明,如下所示:Number类型有以下6种类型Byte类型......