QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#9665#5. 在线 O(1) 逆元Samsara_soul#100 ✓5096ms18516kbC++1.8kb2021-04-09 10:05:512024-11-05 21:46:12

Judging History

你现在查看的是最新测评结果

  • [2024-11-05 21:46:12]
  • 管理员手动重测本题所有提交记录
  • 测评结果:100
  • 用时:5096ms
  • 内存:18516kb
  • [2024-11-05 21:44:04]
  • 管理员手动重测该提交记录
  • 测评结果:100
  • 用时:4346ms
  • 内存:18816kb
  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-02-28 14:35:59]
  • 评测
  • 测评结果:100
  • 用时:5798ms
  • 内存:17164kb
  • [2021-04-09 10:05:51]
  • 提交

answer

#include <bits/stdc++.h>
#include "inv.h"
#define rep(i, a, b) for (int i = (a); i <= int(b); i++)
#define per(i, a, b) for (int i = (a); i >= int(b); i--)
#define fir first
#define sec second
#define tct template <class type>
using namespace std;

typedef long long ll;
const int M = 1e3, M2 = M * M;
const int P=998244353, K = P / M;
int T, A, frac[M2 + 5], sum[M2 + 5], N, F[M2 + 5], I[1000005];

inline void red(int &x) { x += x >> 31 & P; }
tct inline void cmax(type &x, type y) { x < y ? x = y : 0; }
tct inline void cmin(type &x, type y) { x > y ? x = y : 0; }

inline int get(int x) { return x < 0 ? 0 : sum[x]; }
tct inline type my_abs(type x) { return x < 0 ? -x : x; }

int inv(int a) {
    static int x, y, u, v, w, p, q, k, d;
    static ll c;
    if (a <= K)
        return I[a];
    if (P - a <= K)
        return P - I[P - a];
    x = ll(M2) * a / P;
    y = get(x - 1);
    rep(i, 0, 114514) {
        u = i >> 1;
        if (i & 1) {
            v = y - u;
            if (v <= 0)
                continue;
            w = F[v];
        } else {
            v = A - y - u;
            if (v <= 0)
                continue;
            w = F[N + 1 - v];
        }
        q = w / M, p = w - M * q;
        c = ll(a) * q - ll(p) * P;
        if (my_abs(c) <= K) {
            k = q, d = c;
            break;
        }
    }
    return ll(k) * (d > 0 ? I[d] : P - I[-d]) % P;
}

 
void init(int p) 
{ 
    rep(q, 1, M) rep(p, 1, q - 1) {
        int i = ll(M2) * p / q;
        if (sum[i])
            continue;
        frac[i] = M * q + p, sum[i] = 1;
    }
    rep(i, 1, M2) if (sum[i]) F[++N] = frac[i];
    rep(i, 1, M2) sum[i] += sum[i - 1];
    A = sum[M2];
    I[1] = 1;
    rep(i, 2, K) I[i] = ll(P - P / i) * I[P % i] % P;
}

Details


Pretests


Final Tests

Test #1:

score: 10
Accepted
time: 13ms
memory: 18100kb

Test #2:

score: 20
Accepted
time: 535ms
memory: 17472kb

Test #3:

score: 30
Accepted
time: 2563ms
memory: 18324kb

Test #4:

score: 20
Accepted
time: 4099ms
memory: 17876kb

Test #5:

score: 20
Accepted
time: 5096ms
memory: 18516kb