王国里又双叒叕来了一头恶龙,国王要征集勇士去杀死这头恶龙。王国里一共有n个佣兵团,每个佣兵团里有ai名勇士,每名勇士的攻击力为vij,假定恶龙的生命力值为k。现在国王只想派不同的两个佣兵团里的两名勇士去完成这个任务,当两名勇士的攻击力之和大于等于k时,表明他们可以完成任务。统计一共多少种方案。
输入格式
第一行为正整数t(≤10),表示数据组数;每组数据中,第一行为正整数n(≤1000)和k(≤109),接下来n行,每行第一个正整数ai(≤100),表示这个佣兵团的勇士个数,接下来ai个正整数vij(≤109)表示每名勇士的攻击力。
输出格式
对于每组数据,输出合理的方案数。
输入/输出例子1
输入:
1
3 1
1 2
1 2
2 1 1
输出:
5
解释在程序中:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1005, M=105;
int k, a[N], v[N][M], all[N*M];
int main(){
int t, n;
cin>>t;
while (t--){
cin>>n>>k;
int tot=0;
for (int i=0; i<n; i++){
cin>>a[i];
for (int j=0; j<a[i]; j++){
cin>>v[i][j];//v[i]记录本组佣兵
all[tot++]=v[i][j];//all记录所有佣兵
}
sort(v[i], v[i]+a[i]);//本组佣兵
}
sort(all, all+tot);//所有佣兵排序
ll ans=0;
for (int i=0; i<n; i++){
for (int j=0; j<a[i]; j++){
int pos;
//lower_bound(begin,end,num)返回指向大于等于num的第一个值的位置,使用二分查找的方法
//upper_bound(begin,end,num) 返回指向大于num的第一个值的位置
pos=lower_bound(all, all+tot, k-v[i][j])-all;
ans+=tot-pos;//所有数中大于k-v[i][j]的
pos=lower_bound(v[i], v[i]+a[i], k-v[i][j])-v[i];
ans-=a[i]-pos;//减去第i个团里中大于k-v[i][j]的
}
}
cout<<ans/2<<endl;//重复计算,所以除以2
}
return 0;
}
/*
把每个佣兵团勇士的攻击力排序,再把所有勇士的攻击力合起来排序,
枚举第i个佣兵团的第j个勇士,其攻击力为v[i][j],要想找到一个满
足条件的勇士,其攻击力需大于k-v[i][j],先从所有勇士中二分搜索得
到第一个攻击力大于k-v[i][j]的勇士,那么这个勇士和后面的勇士都满足条件,
但是要去掉同一个佣兵团的勇士,再在v[i]中二分搜索找到第一个攻击力大于
k-v[i][j]的勇士,减掉即可
*/