题意:给定数组 a[0]~a[n-1], -1e9<=a[i]<=1e9 在其中找数 x,使得
min( |x-y|, |x+y| ) <= |x| < |y| <= max( |x-y|, |x+y| )
化简后就是 | y |<=2*| x |, x<=y
数据都取abs
一个简单的二分
wa在最大值上了
习惯上拿MOD当最大值了
二分最右边界的值设为MOD了 结果数据范围比MOD大
呜 下次MOD就专门做最大余数了
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<string> #include<algorithm> #include<map> #include<queue> #include<stack> #include<list> #include<set> using namespace std; typedef long long ll; typedef pair<ll,ll> p; typedef long double ld; #define mem(x) memset(x, 0, sizeof(x)) #define me(x) memset(x, -1, sizeof(x)) #define fo(i,n) for(ll i=0; i<n; i++) #define sc(x) scanf("%lf", &x) #define pr(x) printf("%lld\n", x) #define pri(x) printf("%lld ", x) #define lowbit(x) x&-x const ll MOD = 1e9+7; const ll M = 1e18; const ll N = 3e5 +5; ll a[N]; int main() { ll i, j, k; ll n, m, t; cin>>n; for(i=0 ;i<n; i++) { cin>>a[i]; a[i]=abs(a[i]); } sort(a,a+n); ll l, r, ans=0; a[n]=MOD; for(i=0; i<n; i++) { l=i; r=n; k=2*a[i]; ll mid; while(l<=r) { mid=(l+r)/2; if(a[mid]>k) r=mid-1; else if(a[mid]<k) l=mid+1; else { if(a[mid]==a[mid+1]) {mid++;break;} else break; } } //cout<<"aaa"<<mid<<endl; if(a[mid]<=k) { ans+=mid-i; } else { if(a[mid-1]<=k) ans+=mid-1-i; } } cout<<ans<<endl; return 0; }