题意: 在任意俩个班级中个选一人 使得他们的和大于Dudu的智商
思路:枚举一个班级中的每个人再对另一个二分查找

1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cctype> 5 #include <cmath> 6 #include <ctime> 7 #include <string> 8 #include <map> 9 #include <stack> 10 #include <set> 11 #include <vector> 12 #include <algorithm> 13 #include <iostream> 14 using namespace std; 15 typedef long long ll; 16 #define PI acos( -1.0 ) 17 const double E = 1e-8; 18 const int NO = 1000 + 5, NI = 100 + 5; 19 ll a[NO][NI], b[NO]; 20 ll s[NO*NI]; 21 ll n, m; 22 23 ll Solve( ll ss[], ll l, ll r, ll key ) 24 { 25 ll R = r; 26 ll ans = -1; 27 while( l <= r ) 28 { 29 ll mid = ( l+r ) >> 1; 30 if( ss[mid] > key ) ans = mid; 31 if( ss[mid] > key ) r = mid - 1; 32 else l = mid + 1; 33 } 34 if( ans == -1 ) return 0; 35 return R - ans + 1; 36 } 37 38 int main() 39 { 40 int T; 41 scanf( "%d", &T ); 42 while( T-- ) 43 { 44 ll cur = 0; 45 scanf( "%I64d%I64d", &n, &m ); 46 for( ll i = 0; i < n; ++i ) 47 { 48 scanf( "%I64d", &b[i] ); 49 for( ll j = 0; j < b[i]; ++j ) { 50 scanf( "%I64d", &a[i][j] ); 51 s[cur++] = a[i][j]; 52 } 53 } 54 for( ll i = 0; i < n; ++i ) 55 sort( a[i], a[i]+b[i] ); 56 sort( s, s+cur ); 57 ll ans = 0; 58 for( ll i = 0; i < n; ++i ) 59 for( ll j = 0; j < b[i]; ++j ) 60 { 61 ll t1 = Solve( s, 0, cur-1, m-a[i][j] ); 62 ll t2 = Solve( a[i], 0, b[i]-1, m-a[i][j] ); 63 ans += t1 - t2; 64 } 65 printf( "%I64d ", ans >> 1 ); 66 } 67 return 0; 68 }