CodeForces #672 Div2 1420D Rescue Nibel!

题目链接

1420D

题解

题意

给出n段区间,从中找到k个区间存在交集,每个区间可以被选任意次,求这样的找法有多少种。

思路

我们给区间左端点赋值1,给区间右端点赋值-1, 排序后遍历即可求得在当前节点之前有多少个区间和该节点所在的区间有交集。

题目要求找到k个区间,用一下组合数就好(注意取模)。

AC代码

#include <bits/stdc++.h>

using namespace std;
//#pragma GCC optimize(2)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define ull unsigned long long
#define ll long long
#define rep(i, x, y) for(int i=x;i<=y;i++)
#define mms(x, n) memset(x, n, sizeof(x))
#define mmc(A, tree) memcpy(A, tree, sizeof(tree))
#define eps (1e-8)
#define PI (acos(-1.0))
#define INF (0x3f3f3f3f)
#define mod (ll)(998244353)
typedef pair<int, int> P;

int const N = 3e5 + 10;

struct Node {
    
    
    ll x, c;

    Node(ll a, ll b) : x(a), c(b) {
    
    }

    bool operator<(const Node &a) const {
    
    
        if (x == a.x) return c < a.c;
        return x < a.x;
    }
};

vector<Node> v;
ll n, k;
ll l, r;

ll FastPower(ll a, ll b) {
    
    
    ll ans = 1;
    while (b) {
    
    
        if (b & 1) ans = ans * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return ans % mod;
}

ll fac[N];

ll C(ll a, ll b) {
    
    
    if (a < b) return 0;
    return ((((fac[a] % mod) * (FastPower(fac[a - b], mod - 2) % mod)) % mod) * (FastPower(fac[b], mod - 2) % mod)) % mod;
}

int main() {
    
    
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    cin >> n >> k;
    fac[0] = 1;
    for (int i = 1; i <= N - 10; i ++) {
    
    
        fac[i] = fac[i - 1] * i % mod;
    }
    rep(i, 1, n) {
    
    
        cin >> l >> r;
        v.emplace_back(Node(l, 1));
        v.emplace_back(Node(r + 1, -1));
    }
    sort(v.begin(), v.end());
    ll cnt = 0, ans = 0;
    for (auto it : v) {
    
    
        if (it.c == 1) ans = ((ans % mod) + C(cnt, k - 1) % mod) % mod;
        ans %= mod;
        cnt += it.c;
    }
    cout << ans << "\n";
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_45934120/article/details/108875715