HDU 5101 Select 二分

来源:互联网 发布:python自然语言处理 编辑:程序博客网 时间:2024/06/05 19:59

题意:给出N个班级,每个班级有M个学生,每个学生有个IQ值,问有多少对学生,他们的IQ值加起来>K。(两名学生不能来自同一个班级)

思路:升序排序之后,对于每个学生IQ值,可以二分出序列中(K+1IQ)的值的位置,因为不能来自同一个班级,所以要把同班级中(K+1IQ)的值减掉,这个也是可以二分的。

坑点:二分的时候注意left,rightmid的关系,搞得不好就陷入了死循环。

http://acm.hdu.edu.cn/showproblem.php?pid=5101

/*********************************************    Problem : HDU 5101    Author  : NMfloat    InkTime (c) NM . All Rights Reserved .********************************************/#include <map>#include <set>#include <queue>#include <cmath>#include <ctime>#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>#define rep(i,a,b)  for(int i = a ; i <= b ; i ++)#define rrep(i,a,b) for(int i = b ; i >= a ; i --)#define repE(p,u) for(Edge * p = G[u].first ; p ; p = p -> next)#define cls(a,x)   memset(a,x,sizeof(a))#define eps 1e-8using namespace std;const int MOD = 1e9+7;const int INF = 0x3f3f3f3f;const int MAXN = 1e5;const int MAXE = 2e5;typedef long long LL;int T,n,m,k;int a[1005][105];int M[1005];int A[100005];int num;void input() {    scanf("%d %d",&n,&k); k++;    num = 1;    rep(i,1,n) {        scanf("%d",&m);        M[i] = m;        rep(j,1,m) { scanf("%d",&a[i][j]) ; A[num++] = a[i][j] ; }        sort(a[i]+1,a[i]+m+1);    }    sort(A+1,A+num);}int erfen1(int value) {//寻找最小的>=value的数    if(value > A[num-1]) return 0;    int left = 1 , right = num - 1;    int mid ;    while(left < right) {        mid = (left + right) >> 1;        if(A[mid] < value)left = mid + 1;        else right = mid ;    }    return num - left;}int erfen2(int value,int ia) {    if(value > a[ia][M[ia]]) return 0;    int left = 1 , right = M[ia];    int mid ;    while(left < right) {        mid = (left + right) >> 1;        if(a[ia][mid] < value)left = mid + 1 ;        else right = mid ;    }    return M[ia] + 1 - left;}void solve() {    int tmp1,tmp2;    long long ans = 0;    rep(i,1,n) {        rep(j,1,M[i]) {            tmp2 = erfen1(k-a[i][j]);            tmp1 = erfen2(k-a[i][j],i);            //printf("%d %d\n",tmp1,tmp2);            ans += (LL)(tmp2 - tmp1);        }    }    printf("%I64d\n",ans/2);}int main(void) {    //freopen("a.in","r",stdin);    scanf("%d",&T);    while(T--) {    //while(~scanf("%d %d",&n,&m)) {        input();        solve();    }    return 0;}
0 0
原创粉丝点击