1 条题解

  • 0
    @ 2024-11-1 8:51:53

    考察分类讨论和二分查找

    首先我们需要理解这两个条件的本质含义,由于条件包含绝对值,我们将分符号讨论:

    1.如果x和y的符号相同,即都是正数或都是负数,那么:

    • min(xy,x+y)=xy=xymin(|x-y|,|x+y|)=|x-y|=||x|-|y||
    • max(xy,x+y)=x+y=x+ymax(|x-y|,|x+y|)=|x+y|=|x|+|y|

    2.如果x和y的符号不同,即一个是正数,一个是负数,那么:

    • min(xy,x+y)=x+y=xymin(|x-y|,|x+y|)=|x+y|=||x|-|y||
    • max(xy,x+y)=xy=x+ymax(|x-y|,|x+y|)=|x-y|=|x|+|y|

    不难发现,对于max(xy,x+y)=x+ymax(x,y)max(|x-y|,|x+y|) = |x|+|y| \geq max(|x|,|y|)是恒成立的。

    所以我们只需要考虑min(xy,x+y)=x+y=xymin(x,y)min(|x-y|,|x+y|)=|x+y|=||x|-|y|| \leq min(|x|,|y|) 。 不妨按绝对值排序,假设xy|x|\leq|y|,那么:

    • $||x|-|y|| \leq min(|x|,|y|) ==> |y|-|x|\leq |x| ==> |y|\leq 2*|x|$
    • 所以问题转化为了对于当前xx,所有小于等于2x2*|x|的点,都是其合法yy
    #include <bits/stdc++.h>
    using namespace std;
    int binarySearch(vector<int> &a, int target) {
    	int l = 0, r = a.size();
    	while (l < r) {
    		int mid = l + r >> 1;
    		if (a[mid] > target) {
    			r = mid;
    		} else {
    			l = mid + 1;
    		}
    	}
    	return l - 1;
    }
    long long solve(vector<int> &a) {
    	for (int i = 0; i < a.size(); i++)
    		a[i] = abs(a[i]);
    	sort(a.begin(), a.end());
    	long long ans = 0;
    	for (int i = 0; i < a.size(); i++) {
    		ans += binarySearch(a, 2 * a[i]) - i;
    	}
    	return ans;
    }
    int main() {
    	int n;
    	cin >> n;
    	vector<int> a(n);
    	for (int i = 0; i < n; i++)
    		cin >> a[i];
    	cout << solve(a) << endl;
    	return 0;
    }
    
    • 1

    信息

    ID
    23
    时间
    1000ms
    内存
    256MiB
    难度
    6
    标签
    递交数
    43
    已通过
    13
    上传者