#2#3TLE求助(用了二分)

P1102 A-B 数对

```cpp #include<iostream> #include<algorithm> #include<cstdio> #include<math.h> using namespace std; int a[200500]; int qceil(double a) { int s = (int)a; if (a - s > 1e-6) { s++; } return s; } int main() { long long n, c,k,cnt=0;//不开long long见祖宗 scanf("%d%d", &n, &c); for (int i = 0; i < n; i++) { scanf("%d", &a[i]); } int left = 0, right = n - 1; sort(a, a + n); for (int i = n - 1; i >= 0; i--) {//按照你原来的写法,遇上20w个1又如何应对呢 k = a[i] - c; left = 0, right = i; while (left < right) { if (k <= a[(left + right) / 2]) right = (left + right) / 2; else if (right - left != 1) { left = (left + right) / 2; } else { left = qceil((left * 1.0 + right) / 2); } }//以上while循环未改动 right=i;//接下来是重头戏,此时left已经定位好了,把right反回去,重新二分查找 int t=left;//记录left的位置,后面有大用 while (left < right) { if (k < a[(left + right) / 2])//这里去掉了等于号,意思为,当遇到相同的数时,left向右移 right = (left + right) / 2; else if (right - left != 1) { left = (left + right) / 2; } else { left = qceil((left * 1.0 + right) / 2); } }//好了,right也定位了 if(k==a[t]) cnt+=right-t;//right-t的意思是k的个数 } printf("%lld", cnt);//不开long long见祖宗,#3不tle也得wa return 0; } /*既然用c++了,不考虑用强大的STL吗? upper_bound(),意为返回所寻找的数在数组中最后出现的位置 lower_bound(),返回所寻找的数在数组中第一次出现的位置 所以 right-t=upper_bound(a,a+n,k)-lower_bound(a,a+n,k)*/
by Silvestorm @ 2023-11-02 12:00:18


@[Silvestorm](/user/1098851) OrzOrzOrz
by Kotori_Kawaii @ 2023-11-02 14:41:43


@[Silvestorm](/user/1098851) 哥你这思路太清晰了 我根本没想到再次二分 确实二分完之后我的操作又是暴力枚举了 太通透了QAQ
by Kotori_Kawaii @ 2023-11-02 14:50:46


@[Silvestorm](/user/1098851) 健宁也跟我说了让我了解一下这方面 正在努力实现ing qwq
by Kotori_Kawaii @ 2023-11-02 14:53:29


@[Kotori_Kawaii](/user/1053560) 某些题用c++确实方便,我是支持你学c++的
by Silvestorm @ 2023-11-02 15:08:56


@[Silvestorm](/user/1098851) (*^▽^*)
by Kotori_Kawaii @ 2023-11-02 15:12:32


|