洛谷P1102 A-B数对
双指针做法:
反过来,从后往前看也是一样的:
#include <iostream> #include <stdio.h> #include <algorithm> #include <string> #include <cmath> #define For(i, j, n) for (int i = j; i <= n; ++i) using namespace std; const int N = 2e5 + 5; int n, c; int a[N]; int main() { scanf("%d%d", &n, &c); For(i, 1, n) scanf("%d", a + i); sort(a + 1, a + n + 1); /*for (int i = 1; i <= n; i++) cout << i << " "; puts(""); for (int i = 1; i <= n; i++) cout << a[i] << " "; cout << endl;*/ // int r1 = 1, r2 = 1; long long ans = 0; /*for(int i = 1; i <= n; i++) { int k = a[i] + c; while(r1 <= n && a[r1] < k) r1++; while(r2 <= n && a[r2] <= k) r2++; if(a[r1] == k && a[r2 - 1] == k) ans += r2 - r1; }*/ int l1 = 1, l2 = 1; for(int i = 1; i <= n; i++) { int k = a[i] - c; while(l1 <= n && a[l1] < k) l1++; while(l2 <= n && a[l2] <= k) l2++; if(a[l1] == k && l2 >= 2 && a[l2 - 1] == k) ans += l2 - l1; } printf("%lld\n", ans); return 0; }
另外要注意的是,这道题虽然N只有1e5数量级,但ans还是需要开long long的,我们可以分析一下ans的范围:
考虑最极端的情况:
a[]由一系列相等的部分连接而成:
如1 1 1 1 1 …… 2 2 2 2 2
我们简化一下情况,假设每一段数字的数量都相同且为k,那么ans就是:
(为了方便,不考虑向下取整)
我们令k=n/2,就可以让ans来到n^2数量级,从而爆int
本文作者:smartljy
本文链接:https://www.cnblogs.com/smartljy/p/18107119
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步