题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5101
题意:给定一些集合,选择两个来自不同集合的数,加和大于k,问有多少种选择方案
答案=从所有数中选择的两个加和大于k的数的方案数-在同一个集合中选择的两个加和大于k的数的方案数
而对于同一个集合中选择的两个加和大于k的方案数是可以直接排序然后利用单调性快速统计出来的。
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#define LL __int64
using namespace std;
int t;
int n,k;
int main()
{
scanf("%d",&t);
while(t--)
{
vector<int>q[1100];
scanf("%d%d",&n,&k);
for(int i=1; i<=n; i++)
{
int m;
scanf("%d",&m);
for(int j=1; j<=m; j++)
{
int x;
scanf("%d",&x);
q[i].push_back(x);
q[0].push_back(x);
}
sort(q[i].begin(),q[i].end());
}
sort(q[0].begin(),q[0].end());
LL ans=0;
for(int i=1; i<=n; i++)
{
for(int j=0; j<(int)q[i].size(); j++)
{
int v=q[i][j];
LL num1=q[0].end()-lower_bound(q[0].begin(),q[0].end(),k-v+1);
LL num2=q[i].end()-lower_bound(q[i].begin(),q[i].end(),k-v+1);
ans+=num1-num2;
}
}
printf("%I64d\n",ans/2);
}
return 0;
}