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\n",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\n",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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM