分组求数对和
作者:互联网
解题思路
n个小朋友 每人有任意个数字,从两个不同小朋友任意去一个数使得和大于k,问有多少种取法?
可以通过vector容器来方便的解决不同小朋友不同手牌的问题
通过对每个小朋友手牌以及所有手牌排序后二分作差,可以查到与该小朋友的另一取值共有多少种不同取法,然后相加得到
最后还要记得对答案进行减半操作,因为我们队一组数对算了两次 比如(1,2) (2,1)
解题代码
#include<bits/stdc++.h>
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<int> vall;
vector<int> v[N];
int get(vector<int> & 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 << ans/2ll % Mod << endl;
return 0;
}
标签:vall,int,rep,vector,分组,求数,小朋友,define 来源: https://www.cnblogs.com/laowang-blog/p/16490924.html