雙指標做法:
反過來,從後往前看也是一樣的:
#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就是:
$\frac{n}{k} \times k^{2} = nk $
(為了方便,不考慮向下取整)
我們令k=n/2,就可以讓ans來到n^2數量級,從而爆int