题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5101
思路:利用单调性求出总的符合要求的对数ans,再求出班级里符合的对数sum,两者相剪;
代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
typedef long long ll;
using namespace std;
ll c[100005];
ll m[1005];
ll v[1005][105];
int main()
{
ll t,n,k,L,i,j,p,ans,sum;
scanf("%lld",&t);
while(t--)
{
scanf("%lld%lld",&n,&k);
L = 0;
for(i=1;i<=n;i++)
{
scanf("%lld",&m[i]);
for(j=1;j<=m[i];j++)
{
scanf("%lld",&v[i][j]);
c[L++] = v[i][j];
}
sort(v[i]+1,v[i]+1+m[i]);
}
sort(c,c+L);
p = L-1;
ans = 0;
for(i=0;i<L;i++)//总对数
{
while(i<p && c[p]+c[i]>k)
{
p--;
}
if(p>i)
ans += L-1-p;
else
ans += L-1-i;
// cout <<"ans = "<<ans<<endl;
}
sum = 0;
for(i=1;i<=n;i++)//班级内对数
{
p = m[i];
for(j=1;j<=m[i];j++)
{
while(j<p && v[i][j]+v[i][p]>k)
{
p--;
}
if(p>j)
sum += m[i]-p;
else
sum += m[i]-j;
// cout <<"sum = "<<sum<<endl;
}
}
printf("%lld\n",ans-sum);
}
return 0;
}
思路来源:https://blog.csdn.net/qinzhenhua100/article/details/40948947
二分法:http://www.cnblogs.com/syhandll/p/4936971.html?tdsourcetag=s_pctim_aiomsg