其他分享
首页 > 其他分享> > 分组求数对和

分组求数对和

作者:互联网

image

解题思路

 	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