zoukankan      html  css  js  c++  java
  • upper_bound和lower_bound的用法

    首先介绍这两种函数是什么意思

    upper_bound是找到大于t的最小地址,如果没有就指向末尾

    lower_bound是找到大于等于t的最小地址

    题目链接:https://vjudge.net/contest/231314#problem/E

    You are given n integers a1, a2, ..., an. Find the number of pairs of indexes i, j (i < j) that ai + aj is a power of 2 (i. e. some integer x exists so that ai + aj = 2x).

    Input

    The first line contains the single positive integer n (1 ≤ n ≤ 105) — the number of integers.

    The second line contains n positive integers a1, a2, ..., an (1 ≤ ai ≤ 109).

    Output

    Print the number of pairs of indexes i, j (i < j) that ai + aj is a power of 2.

    Examples
    Input
    4
    7 3 2 1
    Output
    2
    Input
    3
    1 1 1
    Output
    3
    Note

    In the first example the following pairs of indexes include in answer: (1, 4) and (2, 4).

    In the second example all pairs of indexes (i, j) (where i < j) include in answer.

    题目大意:输入n,代表有n个数,接下来有n个数,问你两个数相加的和是2的整数次幂的个数

    个人思路:觉得这道题并不难,然后自己写一遍超时了(没有用二分查找),然后改为用二分,还是超时,这就有有点难受了,后来实在不知道

    哪里可以优化,只能百度了

    先看一下自己超时的代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<stdio.h>
    #include<string.h>
    #include<cmath>
    #include<math.h>
    #include<algorithm>
    #include<set>
    #include<queue>
    typedef long long ll;
    using namespace std;
    const ll mod=1e9+7;
    const int maxn=1e5+10;
    const ll maxa=1e10;
    #define INF 0x3f3f3f
    ll b[35];
    //#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    void solve()
    {
        ll p=1;
        for(int i=1;i<=33;i++)
        {
            p*=2;
            b[i]=p;
        }
    }
    bool judge(ll n,int l,int r)
    {
        int mid=(l+r)/2;
        while(l<=r)
        {
            if(n>b[mid])
            {
                l=mid+1;
            }
            else if(n<b[mid])
                r=mid-1;
            else if(n==b[mid])
                return true;
            mid=(l+r)/2;
        }
        return false;
    }
    int main()
    {
        solve();
        ll ans=0;
        ll a[maxn];
        int n;
        //cin>>n;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%lld",&a[i]);
            //cin>>a[i];
        for(int i=0;i<n;i++)
        {
            for(int j=i+1;j<n;j++)//其实这里也是可以优化的,自己没想到罢了
            {
                if(judge(a[i]+a[j],0,33))        
                ans++;
            }
        }
        printf("%lld
    ",ans);
       // cout<<ans<<endl;
    return 0; }

    然后看一下ac 代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<stdio.h>
    #include<string.h>
    #include<cmath>
    #include<math.h>
    #include<algorithm>
    #include<set>
    #include<queue>
    typedef long long ll;
    using namespace std;
    const ll mod=1e9+7;
    const int maxn=1e5+10;
    const ll maxa=1e10;
    #define INF 0x3f3f3f
    ll b[35];
    //#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    void solve()
    {
        ll p=1;
        for(int i=1;i<=33;i++)
        {
            p*=2;
            b[i]=p;
        }
    }
    int main()
    {
        solve();
        ll ans=0,tmp;
        ll a[maxn];
        int n;
        //cin>>n;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%lld",&a[i]);
        sort(a,a+n);
            //cin>>a[i];
        for(int i=0;i<n;i++)//只要遍历一遍就够了
        {
            for(int j=1;j<=33;j++)
            {
                tmp=b[j]-a[i];//tmp是剩下的那个数
                if(tmp>0)
                    ans+=upper_bound(a+i+1,a+n,tmp)-lower_bound(a+i+1,a+n,tmp);//大于tmp的数的下标减去大于等于tmp的数的下标,就知道有没有等于tmp的数了
            }
        }
        printf("%lld
    ",ans);
       // cout<<ans<<endl;
        return 0;
    }

     关于lower_bound和upper_bound的第二种用法

    int t=lower_bound(a,a+n,k)-a   返回第一个大于等于k的下标,如果k比数组里面所有的数都大,就返回a+n,如果k比所有数都小,返回第一个元素下标

    int t=upper_bound(a,a+n,k)-a  返回第一个大于k的下标,如果k比数组所有元素都大,就返回a+n,如果k比所有数都小,返回第一个元素下标

    题目链接:https://vjudge.net/contest/231315#problem/D

    Vasiliy likes to rest after a hard work, so you may often meet him in some bar nearby. As all programmers do, he loves the famous drink "Beecola", which can be bought in n different shops in the city. It's known that the price of one bottle in the shop i is equal to xi coins.

    Vasiliy plans to buy his favorite drink for q consecutive days. He knows, that on the i-th day he will be able to spent mi coins. Now, for each of the days he want to know in how many different shops he can buy a bottle of "Beecola".

    Input

    The first line of the input contains a single integer n (1 ≤ n ≤ 100 000) — the number of shops in the city that sell Vasiliy's favourite drink.

    The second line contains n integers xi (1 ≤ xi ≤ 100 000) — prices of the bottles of the drink in the i-th shop.

    The third line contains a single integer q (1 ≤ q ≤ 100 000) — the number of days Vasiliy plans to buy the drink.

    Then follow q lines each containing one integer mi (1 ≤ mi ≤ 109) — the number of coins Vasiliy can spent on the i-th day.

    Output

    Print q integers. The i-th of them should be equal to the number of shops where Vasiliy will be able to buy a bottle of the drink on the i-th day.

    Example
    Input
    5
    3 10 8 6 11
    4
    1
    10
    3
    11
    Output
    0
    4
    1
    5
    Note

    On the first day, Vasiliy won't be able to buy a drink in any of the shops.

    On the second day, Vasiliy can buy a drink in the shops 1, 2, 3 and 4.

    On the third day, Vasiliy can buy a drink only in the shop number 1.

    Finally, on the last day Vasiliy can buy a drink in any shop.

    题目大意:输入n,代表有n个商店,下面n个数代表每个商店卖酒的价格,输入m,接下来m个数,代表有多少前,问每一次能在多少个商店买酒

    超快能解决,用upper_bound

    先把所有的商店价格按从小到大排序,然后找到第一个大于自己拥有钱的下标就行了

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<stdio.h>
    #include<string.h>
    #include<cmath>
    #include<math.h>
    #include<algorithm>
    #include<set>
    #include<queue>
    typedef long long ll;
    using namespace std;
    const ll mod=1e9+7;
    const int maxn=1e5+10;
    const ll maxa=1e10;
    #define INF 0x3f3f3f3f3f3f
    int main()
    {
        ll n,m,mo;
        ll a[maxn];
        cin>>n;
        for(ll i=0;i<n;i++)
            cin>>a[i];
        sort(a,a+n);
        cin>>m;
        for(int i=1;i<=m;i++)
        {
            cin>>mo;
            cout<<(upper_bound(a,a+n,mo)-a)<<endl;
        }
        return 0;
    }
    当初的梦想实现了吗,事到如今只好放弃吗~
  • 相关阅读:
    IllegalStateException
    TimeUnit简析
    Cron表达式
    任务调度之Timer与TimerTask配合
    Executor简析
    this逃逸
    SQL、SQL Server、MySQL与Oracle
    数据库与实例
    vw 、vh、vmin 、vmax
    逻辑(内存)分页与物理分页
  • 原文地址:https://www.cnblogs.com/caijiaming/p/9316716.html
Copyright © 2011-2022 走看看