题意:
给出 n 个数,问有多少点对(x,y)满足 |x-y| ≤ |x|,|y| ≤ |x+y|;
(x,y) 和 (y,x) 表示一种答案;
题解:
数形结合;
对于某数 x 查找满足条件 y 有多少个;
①x ≥ 0
y ∈ [x/2 , 2x] ∪ [ -2x , -x/2];
②x < 0
y ∈ [2x , -x/2] ∪ [-x/2 , -2x];
特别注意临界值 x/2 处;
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const int maxn=2e5+50; 5 6 int n; 7 int x[maxn]; 8 9 int F(int a,int b)///查找数组x中有多少数位于[a,b]之间 10 { 11 if(a > b) 12 swap(a,b); 13 int t1=lower_bound(x+1,x+n+1,a)-x; 14 int t2=upper_bound(x+1,x+n+1,b)-x; 15 return t2-t1; 16 } 17 ll Solve() 18 { 19 sort(x+1,x+n+1); 20 21 ll ans=0; 22 for(int i=1;i <= n;++i) 23 { 24 int a,b; 25 if(x[i] >= 0) 26 a=(x[i]+1)/2; 27 else 28 a=(x[i]-1)/2;///不能写成(x[i]-1)>>1; 29 b=x[i]*2;///不能写成b=x[i]<<1; 30 ans += F(a,b); 31 ans += F(-a,-b); 32 ans--;///减掉x[i]本身 33 } 34 return ans>>1;///重复计算,除以2 35 } 36 int main() 37 { 38 scanf("%d",&n); 39 for(int i=1;i <= n;++i) 40 scanf("%d",x+i); 41 printf("%lld\n",Solve()); 42 43 return 0; 44 }