作者:格个蝎子_844 | 来源:互联网 | 2023-10-12 07:19
解题思路n个小朋友每人有任意个数字,从两个不同小朋友任意去一个数使得和大于k,问有多少种取法?可以通过vector容器来方便的解决不同小朋友不同手牌的问题通过对每个小朋友手牌以及
解题思路
n个小朋友 每人有任意个数字,从两个不同小朋友任意去一个数使得和大于k,问有多少种取法?
可以通过vector容器来方便的解决不同小朋友不同手牌的问题
通过对每个小朋友手牌以及所有手牌排序后二分作差,可以查到与该小朋友的另一取值共有多少种不同取法,然后相加得到
最后还要记得对答案进行减半操作,因为我们队一组数对算了两次 比如(1,2) (2,1)
解题代码
#include
using namespace std;
#define rep(i,a,n) for(int i = a; i <= n; i++)
#define per(i,a,n) for(int i = n; i >= a; i--)
#define pb push_back
typedef long long ll;
typedef double db;
#define fr first
#define sc second
const int Mod = 998244353;
const int N = 1e6 + 10;
//模板一定要写对
//了解容斥原理
//巧用stl
vector vall;
vector v[N];
int get(vector & v, int x){
return v.end() - lower_bound(v.begin(), v.end(), x);
}
int main(){
int n,k;
int s;
cin >> n >> k;
int x;
rep(i,1,n){
cin >> s;
rep(j,1,s){
cin >> x;
vall.pb(x);
v[i].pb(x);
}
sort(v[i].begin(),v[i].end());
}
sort(vall.begin(),vall.end());
ll ans = 0;
rep(i,1,n){
int sz = v[i].size();
rep(j,0,sz - 1){
int now = v[i][j];
ans +=(get(vall,k - now) - get(v[i],k - now));
}
}
cout < return 0;
}