Codeforces Round #561 (Div. 2):C - A Tale of Two Lands(two pointers)
程序员文章站
2022-03-11 21:48:39
...
题目大意:有一个序列a,任取其中两个数字x,y,它们的绝对值分别为xi,yi,则可以构成两个区间,第一个区间是[min(xi,yi),max(xi,yi)],第二个区间是[min(abs(x - y),abs(x + y)),max(abs(x - y),abs(x + y))],现在要你统计满足第二个区间完全覆盖第一个区间的 无需对 x,y数。
分析:x,y是任意整数,但负数处理方式和正数完全一样,可以对负数取绝对值,然后原序列再重新排序,这样可以从左往右顺序枚举求得答案。对于答案,显然可以枚举区间来求得,对于每一个左端点,只要右端点的权值 y <= 2 * x,就满足区间覆盖的要求。
然后这题区间具有单调性,枚举区间可以用尺取法,复杂度降为o(n)。
区间单调性是指,大区间满足,子区间一定满足。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 10;
int n,a[maxn];
int main() {
scanf("%d",&n);
for(int i = 1; i <= n; i++) {
scanf("%d",&a[i]);
a[i] = abs(a[i]);
}
sort(a + 1,a + n + 1);
long long ans = 0;
int x,y;
x = y = 1;
while(x <= n) {
while(a[y] <= 2 * a[x] && y <= n) y++;
long long tmp = y - x - 1;
ans += tmp;
x++;
}
cout << ans << endl;
return 0;
}
推荐阅读