夹缝中求和

https://ac.nowcoder.com/acm/problem/213483

写法一:手写二分答案

 1 //x<=ai+aj<=y;
 2 //x-ai<=aj aj<=y-ai;
 3 //a个数的排列方式对最后的答案不会产生影响,那么就可以对a个值排序枚举每个ai,二分处理答案
 4 #include<bits/stdc++.h>
 5 using namespace std;
 6 int n, a[100010], x, y;
 7 int ans=0;
 8 int bs(int l, int r, int p){
 9     int ret=-1;
10     while(l<=r){
11         int mid=(l+r)/2;
12         if(a[mid]>=p){
13             ret=mid;
14             r=mid-1;
15         }
16         else
17             l=mid+1;
18     }
19     return ret;
20 }
21 int be(int l, int r, int p){
22     int ret=-1;
23     while(l<=r){
24         int mid=(l+r)/2;
25         if(a[mid]>p){
26             ret=mid;
27             r=mid-1;
28         }
29         else
30             l=mid+1;
31     }
32     return ret;
33 }
34 int main()
35 {
36     cin>>n>>x>>y;
37     for(int i=0; i<n; i++)cin>>a[i];
38     sort(a, a+n);
39     //for(int i=0; i<n; i++)cout<<a[i]<<" ";cout<<endl;
40     for(int i=0; i<n; i++){
41         int s=bs(i+1, n-1, x-a[i]);//返回大于等于x-v[i]的第一个值的下标
42         int e=be(i+1, n-1, y-a[i]);//返回大于 y-v[i]的第一个值的小标 
43         if(s==-1 || e==-1 || e-s<0)continue;
44         ans+=e-s;
45     }
46     cout<<ans<<endl;
47     return 0;
48 } 

写法二:二分STL

 1 //x<=ai+aj<=y;
 2 //x-ai<=aj aj<=y-ai;
 3 //a个数的排列方式对最后的答案不会产生影响,那么就可以对a个值排序枚举每个ai,二分处理答案
 4 #include<bits/stdc++.h>
 5 using namespace std;
 6 #define ll long long
 7 int main() {
 8     ll a, x, y;
 9     cin >> a >> x >> y;
10     vector<ll>v;
11     for (int i = 0; i < a; i++) cin >> v[i];//读入
12     sort(v.begin(), v.end());//排序
13     ll ans = 0;
14     for(int i=0; i<v.size(); i++) {
15         int S = lower_bound(v.begin() + i + 1, v.end(), x - v[i]) - v.begin();
16         //返回大于等于x-v[i]的第一个值的下标 
17         int E = upper_bound(v.begin() + i + 1, v.end(), y - v[i]) - v.begin();
18         //返回大于    y-v[i]的第一个值的小标 
19         ans += (E - S);
20     }
21     cout << ans << endl;
22     return 0;
23 }
原文地址:https://www.cnblogs.com/tflsnoi/p/14072537.html