QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#4911#5. 在线 O(1) 逆元Qingyu100 ✓4129ms18756kbC++111.8kb2020-10-15 22:38:212024-11-05 21:44:43

Judging History

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

  • [2024-11-05 21:44:43]
  • 管理员手动重测本题所有提交记录
  • 测评结果:100
  • 用时:4129ms
  • 内存:18756kb
  • [2024-11-05 21:41:39]
  • 管理员手动重测本题所有提交记录
  • 测评结果:100
  • 用时:5599ms
  • 内存:18608kb
  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2021-12-19 05:35:57]
  • 评测
  • 测评结果:70
  • 用时:972ms
  • 内存:19324kb
  • [2020-10-15 22:38:21]
  • 提交

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;
int P, 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) 
{
	P = p; K = P / M;
    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: 15ms
memory: 18280kb

Test #2:

score: 20
Accepted
time: 421ms
memory: 17660kb

Test #3:

score: 30
Accepted
time: 2105ms
memory: 17568kb

Test #4:

score: 20
Accepted
time: 3303ms
memory: 18000kb

Test #5:

score: 20
Accepted
time: 4129ms
memory: 18756kb