题目
题解思路
利用STL里的二分函数。(自己写的疯狂WA)
自己写也行。
取i+1到n中小于等于r-a[i]的最大的数的下标
upper_bound(a+i+1,a+n+1,r-a[i])-a-i-1;
取i+1到n中大于等于l-a[i]的最大的数的下标
lower_bound(a+i+1,a+n+1,l-a[i])-a-i-1;
这样时间复杂度为nlogn
符合题目的10e5.
纠结了好久。
AC代码
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int a[200100];
int n,l,r,t1,t2;
int main ()
{
int t;
scanf("%d",&t);
while(t--)
{
long long ans = 0 ;
scanf("%d%d%d",&n,&l,&r);
for (int i = 1 ; i <= n ; i++ )
{
scanf("%d",&a[i]);
}
sort(a+1,a+n+1);
for (int i = 1 ; i < n ; i++ )
{
int s1 = upper_bound(a+i+1,a+n+1,r-a[i])-a-i-1;
int s2 = lower_bound(a+i+1,a+n+1,l-a[i])-a-i-1;
ans+=s1-s2;
}
cout<<ans<<"\n";
}
return 0;
}
自己写的
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int a[200100];
int n,l,r,t1,t2;
int fen(int x)
{
//cout<<x<<"\n";
int p = r-a[x];
int ll = x+1;
int rr = n;
while(ll <= rr)
{
int mid = (ll+rr)/2;
if (a[mid]>p)
{
rr = mid-1;
}else
{
ll = mid+1;
}
// cout<<rr<<" "<<ll<<" \n";
}
// cout<<"\n";
p = l-a[x];
t1 = x+1;
t2 = n;
while(t1<=t2)
{
int mid = (t1+t2)/2;
if (a[mid]<p)
{
t1 = mid+1;
}else
{
t2 = mid-1;
}
// cout<<t1<<" "<<t2<<" \n";
}
//cout<<t1<<" "<<rr<<" \n";
if (t1>n ||rr >n)
return 0;
return rr-t1+1;
}
bool cmp (int x1,int x2)
{
return x1 > x2;
}
int main ()
{
int t;
scanf("%d",&t);
while(t--)
{
long long ans = 0 ;
scanf("%d%d%d",&n,&l,&r);
for (int i = 1 ; i <= n ; i++ )
{
scanf("%d",&a[i]);
}
sort(a+1,a+n+1);
for (int i = 1 ; i < n ; i++ )
{
// int s1 = upper_bound(a+i+1,a+n+1,r-a[i])-a-i-1;
// int s2 = lower_bound(a+i+1,a+n+1,l-a[i])-a-i-1;
ans+=fen(i);
}
cout<<ans<<"\n";
}
return 0;
}