ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

5467. 找到最接近目标值的函数值

2020-07-19 17:31:48  阅读:190  来源: 互联网

标签:return 函数 int 线段 ++ ask 5467 目标值 target


题目大意

寻找数组arr的区间l和r,使[l,r]区间内的数&后与target的差值的绝对值最小

思路

有一个很重要的推论就是&运算具有单调递减性,也就是ask(a,r+1)<=ask(l,r)<=ask(l+1,r)。因此我们可以通过滑动数组,当前区间结果>target时,r++;否则l++。
我们用线段树维护区间&的值

class Solution {
public:
    static const int maxn=4*1e5+10;
    int a[maxn];
    int d[maxn];
    void build(int s,int t,int p)
    {
        //p代表线段树的结点号,s和t描述原数组的区间
        if(s==t)
        {
            d[p]=a[s];
            return;
        }
        int m=(s+t)>>1;
        build(s,m,2*p);
        build(m+1,t,2*p+1);
        d[p]=d[2*p]&d[2*p+1];
    }
    int ask(int l,int r,int s,int t,int p)
    {
        //l,r是查询区间;s,t是当前线段树的结点区间,p是线段树当前访问的结点
        if(l<=s&&r>=t)
            return d[p];
        int m=(s+t)>>1;
        if(r<=m)
            return ask(l,r,s,m,2*p);
        if(l>m)
            return ask(l,r,m+1,t,2*p+1);
        return ask(l,m,s,m,2*p)&ask(m+1,r,m+1,t,2*p+1);
    }
    int closestToTarget(vector<int>& arr, int target) {
        int n=arr.size();
        for(int i=0;i<n;i++)
            a[i]=arr[i];
        build(0,n-1,1);
        int l=0,r=0,ans=1e9+1e7;
        while(r<n)
        {
            int t=ask(l,r,0,n-1,1);
            if(t>target)
                r++;
            else
                l++,r=max(l,r);
            ans=min(ans,abs(t-target));
        }   
        return ans;
    }
};

标签:return,函数,int,线段,++,ask,5467,目标值,target
来源: https://www.cnblogs.com/flightless/p/13340505.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有