首先介绍这两种函数是什么意思
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).
InputThe 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).
OutputPrint the number of pairs of indexes i, j (i < j) that ai + aj is a power of 2.
Examples4
7 3 2 1
2
3
1 1 1
3
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; }