QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#104922#6399. Classic: Classical Problemckiseki#WA 8ms7440kbC++204.9kb2023-05-12 15:20:292023-05-12 15:20:31

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-05-12 15:20:31]
  • 评测
  • 测评结果:WA
  • 用时:8ms
  • 内存:7440kb
  • [2023-05-12 15:20:29]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

#ifdef CKISEKI
#define safe cerr << __PRETTY_FUNCTION__ << " line " << __LINE__ << " safe\n"
#define debug(a...) debug_(#a, a)
#define orange(a...) orange_(#a, a)
template <typename ...T>
void debug_(const char *s, T ...a) {
    cerr << "\e[1;32m(" << s << ") = (";
    int cnt = sizeof...(T);
    (..., (cerr << a << (--cnt ? ", " : ")\e[0m\n")));
}
template <typename I>
void orange_(const char *s, I L, I R) {
    cerr << "\e[1;32m[ " << s << " ] = [ ";
    for (int f = 0; L != R; ++L)
        cerr << (f++ ? ", " : "") << *L;
    cerr << " ]\e[0m\n";
}
#else
#define safe ((void)0)
#define debug(...) safe
#define orange(...) safe
#endif

#define all(v) begin(v),end(v)

const int maxn = 1 << 20;
const int mod = 998244353;
const int G = 3;

int modadd(int a, int b) {
    return a + b >= mod ? a + b - mod : a + b;
}
int modsub(int a, int b) {
    return a - b < 0 ? a - b + mod : a - b;
}
int modmul(int64_t a, int64_t b) {
    return static_cast<int>(a * b % mod);
}
int modpow(int e, int p) {
    int r = 1;
    while (p) {
        if (p & 1) r = modmul(r , e);
        e = modmul(e, e);
        p >>= 1;
    }
    return r;
}

int modinv(int z) {
    return modpow(z, mod - 2);
}

struct NTT {
    static_assert (maxn == (maxn & -maxn));
    int roots[maxn];
    NTT () {
        int r = modpow(G, (mod - 1) / maxn);
        for (int i = maxn >> 1; i; i >>= 1) {
            roots[i] = 1;
            for (int j = 1; j < i; j++)
                roots[i + j] = modmul(roots[i + j - 1], r);
            r = modmul(r, r);
        }
    }
    void operator()(int F[], int n, bool inv = false) {
        for (int i = 0, j = 0; i < n; i++) {
            if (i < j) swap(F[i], F[j]);
            for (int k = n >> 1; (j ^= k) < k; k >>= 1)
                ;
        }
        for (int s = 1; s < n; s *= 2) {
            for (int i = 0; i < n; i += s * 2) {
                for (int j = 0; j < s; j++) {
                    int a = F[i + j];
                    int b = modmul(F[i + j + s], roots[s + j]);
                    F[i + j] = modadd(a, b);
                    F[i + j + s] = modsub(a, b);
                }
            }
        }
        if (inv) {
            int invn = modinv(n);
            for (int i = 0; i < n; i++)
                F[i] = modmul(F[i], invn);
            reverse(F + 1, F + n);
        }
    }
} ntt;

int find_primitive(int p) {
    if (p == 2) {
        return 1;
    }

    for (int g = 2; g < p; g++) {
        bool ok = true;
        int x = 1;
        for (int i = 0; i < p - 2; i++) {
            x = 1LL * x * g % p;
            if (x == 1) {
                ok = false;
                break;
            }
        }

        if (ok) {
            return g;
        }
    }
}

void solve() {
    int n, p;
    cin >> n >> p;
    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }

    bool has_zero = false;
    for (int i = 0; i < n; i++) {
        if (a[i] == 0) {
            has_zero = true;
        }
    }

    if (!has_zero) {
        cout << 1 << ' ' << 1 << '\n';
        cout << 0 << '\n';
        return;
    }

    vector<int> f(p);
    vector<int> dlog(p);

    const int gg = find_primitive(p);

    for (int it = 0, x = 1; it < p - 1; it++) {
        dlog[x] = it;
        x = 1LL*x*gg%p;
    }

    int cnt = 0;
    for (int i = 0; i < n; i++) {
        if (a[i] == 0) continue;
        f[ dlog[a[i]] ] = 1;
        cnt += 1;
    }

    int sz = 1;
    while (sz < p * 2) sz *= 2;
    f.resize(sz);
    ntt(f.data(), sz, false);

    orange(all(dlog));
    vector<int> cs;

    const auto ok = [&](int x, bool output = false) {
        if (x >= p)
            return false;

        vector<int> g(sz);
        for (int i = 1; i <= x; i++) {
            g[ dlog[i] ] = 1;
        }

        reverse(g.begin(), g.begin() + p);

        ntt(g.data(), sz, false);
        for (int i = 0; i < sz; i++) {
            g[i] = modmul(g[i], f[i]);
        }
        ntt(g.data(), sz, true);

        orange(g.begin(), g.end());

        for (int i = p-1; i < sz; i++) {
            g[i % (p - 1)] += g[i];
        }

        int mx = *max_element(g.begin(), g.begin() + (p - 1));

        if (output) {
            int prod = 1;
            for (int j = 0; j < p - 1; j++) {
                if (g[p-1-j] == mx) {
                    cs.push_back(prod);
                }
                prod = 1LL*prod*gg % p;
            }
        }

        assert (mx <= x);
        return mx == x;
    };

    // debug(ok(0));
    // debug(ok(1));
    // debug(ok(2));

    // return;
    int ans = 0;
    for (int s = 1 << 20; s; s >>= 1) {
        if (ok(ans + s)) {
            ans += s;
        }
    }
    ok(ans, 1);

    cout << cs.size() << ' ';
    cout << ans + 1 << '\n';
    sort(cs.begin(), cs.end());
    for (size_t i = 0; i < cs.size(); i++) {
        cout << cs[i] << (i+1==cs.size() ? '\n' : ' ');
    }

}

int main() {
    int T;
    cin >> T;
    while (T--)
        solve();

    return 0;
}

详细

Test #1:

score: 100
Accepted
time: 8ms
memory: 7440kb

input:

3
2 3
0 2
3 5
2 3 4
3 5
0 2 3

output:

1 2
2
1 1
0
2 2
2 3

result:

ok 6 lines

Test #2:

score: -100
Wrong Answer
time: 8ms
memory: 7400kb

input:

3
1 2
0
1 2
1
2 2
1 0

output:

1 1
1
1 1
0
1 2
1

result:

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