QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#959984#3090. Inverse Problemxiaoxia#WA 2ms8288kbC++203.3kb2025-04-01 05:26:422025-04-01 05:26:43

Judging History

This is the latest submission verdict.

  • [2025-04-01 05:26:43]
  • Judged
  • Verdict: WA
  • Time: 2ms
  • Memory: 8288kb
  • [2025-04-01 05:26:42]
  • Submitted

answer

#include<bits/stdc++.h>
#define int i64 /* R.I.P */
#define all(x) std::begin(x), std::end(x)
#define rall(x) std::rbegin(x), std::rend(x)
using i64 = long long;
using u64 = unsigned long long;
using ld = long double;

constexpr int M = 998244353;

i64 powp(i64 a, i64 n) {
    a %= M;
    i64 ans = 1;
    while (n) {
        if (n & 1) (ans *= a) %= M;
        (a *= a) %= M;
        n >>= 1;
    }

    return ans;
}

i64 inv(i64 x) {
    return powp(x, M - 2);
}

constexpr int N = 3e5;
i64 fac[N], invfac[N];

void pre() {//      #######组合数预处理时不能超过模数########
    fac[0] = invfac[0] = 1;
    for (int i = 1; i < N; i++) fac[i] = fac[i-1] * i % M;
    invfac[N - 1] = inv(fac[N - 1]);
    for (int i = N - 2; i >= 1; i--) invfac[i] = invfac[i + 1] * (i + 1) % M;
}
 
i64 C(i64 n,i64 m) {
    if (m > n) return 0;
    return fac[n] * invfac[n - m] % M * invfac[m] % M;
}

template<typename T>
struct BIT {
    std::vector<T> a;
    int n;
    BIT(int n_) {//下标从1开始
        a.clear();
        a.resize(n_ + 1);
        n = n_;
    }
    BIT() {}
    BIT(const BIT& bit) {//[可选] 复制bit(很少用)
        n = bit.n;
        a = bit.a;
    }
    T getsum(int x) {//获取[1, x]的和        O(logn)
        T s = 0;
        while (x) {
            s += a[x];
            x -= (x &- x);
        }
        return s;
    }
    void modify(int x, T val) {//单点增加x处的值    O(logn)
        while (x <= n) {
            a[x] += val;
            x += (x &- x);
        }
    }
};

/*
4 5 9 10 2 7 8 3 6 1 

A 中必须有 1
5 2 8 4 6 3 7 1 10


9 7 [3 6 5 1] 2

C(10, )



2 [1 3 4 5]

7 5 4 [3 2 6 1 9]

从小到大确定可以放的位置

看数组中的第一个数,是不是恰好是数组的 mex - 1
如果不是,输出0

否则,所有值域在数组中的元素只能放在数组前面,其它元素随意放,答案为 ((max - min + 1) - m)! * C(n, (max - min + 1))

二分一下前缀 max 
*/

void solve() {
    i64 n, k;
    std::cin >> k >> n;
    std::vector<int> a(n);
    for (auto &i : a) std::cin >> i;

    auto b = a;
    std::sort(all(b));

    int mex = 1;
    for (; mex <= n; mex++) {
        if (b[mex - 1] != mex) break;
    }

    if (b.back() != n && a[0] > mex - 1) {
        std::cout << 0;
        return;
    }

    i64 ans = 1;

    BIT<i64> bit(n + 1);

    for (int i = 1; i <= n + 1; i++) {
        bit.modify(i, 1);
    }

    std::set<int> c;
    for (int i = 1; i <= k; i++) c.insert(i);
    for (auto j : a) c.erase(j);

    std::vector<int> pre(n);
    pre[0] = a[0];
    for (int i = 1; i < n; i++) {
        pre[i] = std::max(pre[i - 1], a[i]);
    }

    for (auto i : c) {
        ans *= bit.getsum((std::lower_bound(all(pre), i) - pre.begin()) + 1);
        bit.modify(1, 1);
    }

    std::cout << ans;

    // int mx = 0, mi = k;
    // for (auto i : a) {
    //     mx = std::max(mx, i);
    //     mi = std::min(mi, i);
    // }

    // std::cout << fac[(mx - mi + 1) - n] * C(k, mx - mi + 1) % M * fac[k - (mx - mi + 1)] % M;
}

signed main() {
    std::cin.tie(0)->sync_with_stdio(false);
    int t = 1;
    pre();
    //std::cin >> t;
    while(t--) solve();
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 2ms
memory: 8288kb

input:

7 2
2 1

output:

2520

result:

wrong answer 1st lines differ - expected: '720', found: '2520'