题目链接:https://vjudge.net/problem/HDU-5101
转自:https://www.cnblogs.com/fanminghui/p/4084192.html
思路:自己朴素写法超时了…网上的是将同班的同学按照value排序,在将所有的同学单独保存,在排一次序。然后遍历每一个同学,他所能匹配到的就是所有符合情况的人-同班中符合情况的人。用upperbound查找第一个大于的数。还要开longlong,注意/2,因为每个同学计算了两次。
#include <bits/stdc++.h>
using namespace std;
vector <int> g[1005];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,k,sum=0;
scanf("%d%d",&n,&k);
for(int i=0; i<=n; i++)
{
g[i].clear();
}
for(int i=1; i<=n; i++)
{
int x,a;
scanf("%d",&x);
for(int j=0; j<x; j++)
{
scanf("%d",&a);
g[i].push_back(a);
g[0].push_back(a);
}
sort(g[i].begin(),g[i].end());
}
sort(g[0].begin(),g[0].end());
long long ans=0;
for(int i=1; i<=n; i++)
{
for(int j=0; j<g[i].size(); j++)
{
int cnt=g[i][j];
int pos1=g[i].end()-upper_bound(g[i].begin(),g[i].end(),k-cnt);
int pos2=g[0].end()-upper_bound(g[0].begin(),g[0].end(),k-cnt);
ans+=pos2-pos1;
}
}
printf("%lld\n",ans/2);
}
return 0;
}