HDU 5101 Select (二分+容斥水过)

Select

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2331    Accepted Submission(s): 663


 

Problem Description

One day, Dudu, the most clever boy, heard of ACM/ICPC, which is a very interesting game. He wants to take part in the game. But as we all know, you can't get good result without teammates.
So, he needs to select two classmates as his teammates.
In this game, the IQ is very important, if you have low IQ you will WanTuo. Dudu's IQ is a given number k. We use an integer v[i] to represent the IQ of the ith classmate.
The sum of new two teammates' IQ must more than Dudu's IQ.
For some reason, Dudu don't want the two teammates comes from the same class.
Now, give you the status of classes, can you tell Dudu how many ways there are.

 

 

Input

There is a number T shows there are T test cases below. (T≤20)
For each test case , the first line contains two integers, n and k, which means the number of class and the IQ of Dudu. n ( 0≤n≤1000 ), k( 0≤k<231 ).
Then, there are n classes below, for each class, the first line contains an integer m, which means the number of the classmates in this class, and for next m lines, each line contains an integer v[i], which means there is a person whose iq is v[i] in this class. m( 0≤m≤100 ), v[i]( 0≤v[i]<231 )

 

 

Output

For each test case, output a single integer.

 

 

Sample Input

 

1 3 1 1 2 1 2 2 1 1

 

 

Sample Output

 

5

 

 

Source

BestCoder Round #17

 

 

Recommend

heyang   |   We have carefully selected several similar problems for you:  6447 6446 6445 6444 6443

#pragma comment(linker, "/STACK:102400000,102400000")
#include<bits/stdc++.h>
using namespace std;

#define debug puts("YES");
#define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++)

#define lrt int l,int r,int rt
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define ll long long

const int  maxn =3e3+5;
const int mod=1e9+7;

ll gcd(ll x,ll y) { return y==0?x:gcd(y,x%y); }
ll powmod(ll x,ll y){ll t;for(t=1;y;y>>=1,x=x*x%mod) if(y&1) t=t*x%mod;return t;}
/*
题目大意:给定若干个集合和一个k值,
要求从不同的两个集合中选择两个数,两个数之和大于k值,
问有多少种选择方案。

二分暴力水过。。。
本来是在树状数组中看到这题的,
树状数组的思想是离散化加二分云云,
怪复杂的,看了半天没懂,
然后自己写了个二分外加小小的容斥就
。。。。。水过了。

大体思想是这样的,就是把每个数存储下来,
然后顺便开个二维数组存储每个集合的元素,
对于每个元素,整体二分得到的结果,
排除掉当前集合中符合答案的结果。
得到的是对答案的贡献。
*/
int n,s,x,m;
int dat[maxn][105];
int tot[1000005],cnt;
ll ans;

int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {
        memset(dat,0,sizeof(dat));cnt=0;

        scanf("%d%d",&n,&s);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&dat[i][0]);
            for(int j=1;j<=dat[i][0];j++)
            {
                    scanf("%d",&dat[i][j]);
                    tot[cnt++]=dat[i][j];
            }
            sort(dat[i]+1,dat[i]+dat[i][0]+1);///从小到大
        }
        sort(tot,tot+cnt);///从小到大排序
        ans=0;
        for(int i=0;i<n;i++)
        {
            for(int j=1;j<=dat[i][0];j++)
            {
                int num1=lower_bound(tot,tot+cnt,s-dat[i][j]+1)-tot;num1=cnt-num1;
                int num2=lower_bound(dat[i]+1,dat[i]+dat[i][0]+1,s-dat[i][j]+1)-dat[i]-1;num2=dat[i][0]-num2;
                ans+=1LL*(num1-num2);
                ///cout<<num1<<" "<<num2<<endl;
            }
        }
        printf("%lld\n",1LL*ans/2);
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值