結果
問題 | No.2327 Inversion Sum |
ユーザー |
|
提出日時 | 2023-05-12 08:53:54 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 40 ms / 2,000 ms |
コード長 | 3,171 bytes |
コンパイル時間 | 988 ms |
コンパイル使用メモリ | 120,616 KB |
最終ジャッジ日時 | 2025-02-12 21:36:33 |
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 30 |
ソースコード
#include <iostream>#include <vector>#include <set>#include <unordered_set>#include <map>#include <unordered_map>#include <cstdio>#include <bitset>#include <queue>#include <deque>#include <algorithm>#include <numeric>#include <cassert>#include <functional>#include <stack>#include <cmath>#include <string>#include <complex>#include <cassert>#define REP(i, N) for (int i = 0; i < (int)N; i++)#define FOR(i, a, b) for (int i = a; i < (int)b; i++)#define ALL(x) (x).begin(), (x).end()using namespace std;constexpr int mod = 998244353;template <int mod>struct ModInt {int x;ModInt() : x(0) {}ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}ModInt& operator+=(const ModInt& p) {if ((x += p.x) >= mod) x -= mod;return *this;}ModInt& operator-=(const ModInt& p) {if ((x += mod - p.x) >= mod) x -= mod;return *this;}ModInt& operator*=(const ModInt& p) {x = (int)(1LL * x * p.x % mod);return *this;}ModInt& operator/=(const ModInt& p) {*this *= p.inverse();return *this;}ModInt operator-() const { return ModInt(-x); }ModInt operator+(const ModInt& p) const { return ModInt(*this) += p; }ModInt operator-(const ModInt& p) const { return ModInt(*this) -= p; }ModInt operator*(const ModInt& p) const { return ModInt(*this) *= p; }ModInt operator/(const ModInt& p) const { return ModInt(*this) /= p; }ModInt inverse() const {int a = x, b = mod, u = 1, v = 0, t;while (b > 0) {t = a / b;swap(a -= t * b, b);swap(u -= t * v, v);}return ModInt(u);}ModInt pow(int64_t n) const {ModInt ret(1), mul(x);while (n > 0) {if (n & 1) ret *= mul;mul *= mul;n >>= 1;}return ret;}friend ostream& operator<<(ostream& os, const ModInt& p) { return os << p.x; }friend istream& operator>>(istream& is, ModInt& a) {int64_t t;is >> t;a = ModInt<mod>(t);return (is);}static int get_mod() { return mod; }};using modint = ModInt<mod>;template <typename T>struct BinaryIndexedTree {vector<T> data;BinaryIndexedTree(int sz) { data.assign(++sz, 0); }T sum(int k) {T ret = 0;for (++k; k > 0; k -= k & -k) ret += data[k];return (ret);}void add(int k, T x) {for (++k; k < data.size(); k += k & -k) data[k] += x;}};int main() {int N, M;cin >> N >> M;int R = N - M;vector<int> A(N, -1), used(N), cum(N + 1);REP(i, M) {int P, K;cin >> P >> K;A[K - 1] = P - 1;used[P - 1] = 1;}vector<int> rest;REP(i, N) {if (!used[i]) rest.push_back(i);cum[i + 1] = cum[i] + (A[i] == -1);}vector<modint> facts(N + 1, 1);FOR(i, 2, N + 1) facts[i] = facts[i - 1] * i;BinaryIndexedTree<int> bit(N + 1);modint ans = facts[R] * R * (R - 1) / 4;int B = 0;REP(i, N) {if (A[i] != -1) {long long C = rest.end() - lower_bound(ALL(rest), A[i]);ans += facts[R - 1] * (C * cum[i] + (R - C) * (cum[N] - cum[i + 1]));ans += facts[R] * (i - cum[i] - bit.sum(A[i]));bit.add(A[i], 1);}}cout << ans << endl;return 0;}