本题思路写代码的时候顺手放进去了这里稍微补充一些
首先数据100%的时候为2*10^5,数据过大两层循环可能存在超时,而常规思路就是两层for循环找答案,放弃该思路
我们先行排序,然后从大到小循环一遍,当前数字减去m后所得到的值是固定的,只需要查找数组中有多少个数字符合条件即可
时间复杂度O(nlogn)
上代码
#include <cstdio>
#include <algorithm>
using namespace std;
#define scnaf scanf
int n,m;
int a[200040];
long long int cnt = 0;
int minn;
int bin_search(int key)
{
int l,r;
l = 1;
r = minn;
int mid;
while(l<r)
{
mid = (l+r)>>1;
if(a[mid] < key)
l = mid+1;
else
r = mid;
}
return l;
}
int main()
{
register int i,j;
//freopen("in","r",stdin);
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)scanf("%d",&a[i]);
sort(a+1,a+1+n);
for(i=n;i>=1;i--)
{
if(a[i] - m <= 0)break;
minn = i;//每次查找都从1到当前位置即可
int fsit,esit;
/*我们要去寻找第一个大于x的数的下标
还有第一个大于x-1的下标
x = a[i] - m
eg:
9 1
1 1 1 3 3 3 3 3 4
我们如何确定一共有多少个3?
fsit = 4
esit = 9
cnt += esit-fsit
如何确定有几个2呢?
fsit = 4
esit = 4
cnt += esit-fsit;
*/
fsit = bin_search(a[i]-m);
esit = bin_search(a[i]-m+1);
cnt += (esit-fsit);
}
printf("%lld\n",cnt);
return 0;
}
后记
有一个点答案整型溢出了,所以cnt用long long