"PKUSC2018" real rankings

Category talk this number ( \ (a_i \) ) does not turn doubled.

If doubled, the \ (\ text {[$ a_i $, $ -1 2 $ a_i]} \) number must be doubled in, otherwise the answer will affect.
If doubled, the \ (\ text {[$ \ lceil \ frac {a_i} {2} \ rceil $, $ a_i-1 $]} \) number must not be doubled within, otherwise the answer will affect .

The remaining number of calculations can be combined to solve, special attention sentence \ (a_i = 0 \) when you want to output \ (C_n ^ k \) .

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;

#define LOG(...) fprintf (stderr, __VA_ARGS__)
#define pb push_back
#define mp make_pair
#define SZ(x) ((int)(x).size())
#define ALL(x) (x).begin(), (x).end()

const int INF = 0x3f3f3f3f, MOD = 998244353;
const LL INFL = 0x3f3f3f3f3f3f3f3fll;

const int N = 100005; 
int n, k, a[N], b[N], fac[N], ifac[N]; 
int binom (int n, int m) {
    if (n < m || n < 0 || m < 0) return 0; 
    return 1LL * fac[n] * ifac[n - m] % MOD * ifac[m] % MOD;
}
int inv (int x) {
    int t = MOD - 2, res = 1; 
    while (t) {
        if (t&1) res = 1LL * res * x % MOD;
        x = 1LL * x * x % MOD;
        t >>= 1; 
    }
    return res; 
}
void work() {
    fac[0] = 1; 
    for (int i = 1; i <= n; i++) fac[i] = 1LL * fac[i - 1] * i % MOD;
    ifac[n] = inv(fac[n]);
    for (int i = n-1; i >= 0; i--) ifac[i] = 1LL * ifac[i + 1] * (i + 1) % MOD;
}
int Q (LL x) {
    if (x < b[1]) return 0;
    int l = 1, r = n, ans = 0;
    while (l <= r) {
        int mid = (l + r) >> 1;
        if (b[mid] <= x) ans = mid, l = mid + 1;
        else r = mid - 1;
    }
    return ans; 
}

int add (int a, int b) {
    int val = a + b;
    if (val >= MOD) val -= MOD;
    return val; 
}
int main() {
#ifdef LiM_817
    freopen ("input.txt", "r", stdin);
//  freopen ("test.out", "w", stdout);
    double cl = clock();
#endif

    cin >> n >> k;
    for (int i = 1; i <= n; i++) scanf ("%d", &a[i]), b[i] = a[i];
    sort (b + 1, b + n + 1);
    work();
    
    for (int i = 1; i <= n; i++) {
        if (!a[i]) {
            printf ("%d\n", binom (n, k)); 
            continue;
        }
        
        int ans = 0; 
        // case 1
        int Lb = a[i] / 2 + (a[i] % 2), Rb = a[i] - 1;
        if (Lb > Rb) ans = add(ans, binom (n - 1, k));
        else {
            int q = Q(Rb) - Q(Lb - 1);
            ans = add(ans, binom (n - 1 - q, k));
        }
        
        Lb = a[i], Rb = 2 * a[i] - 1;
        if (Lb > Rb) ans = add (ans, binom (n - 1, k - 1));
        else {
            int q = Q(Rb) - Q(Lb - 1);
            ans = add (ans, binom (n - q, k - q));
        }
        printf ("%d\n", ans);
    }

#ifdef LiM_817
    cerr << fixed << setprecision(2) << "Time ellapsed: " << ((double)(clock() - cl) / CLOCKS_PER_SEC) << "s\n";
#endif
    return 0;
}

Guess you like

Origin www.cnblogs.com/LiM-817/p/11903483.html