QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#178386#6399. Classic: Classical Problemucup-team1600#WA 1ms3524kbC++209.9kb2023-09-13 22:24:062023-09-13 22:24:07

Judging History

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

  • [2023-09-13 22:24:07]
  • 评测
  • 测评结果:WA
  • 用时:1ms
  • 内存:3524kb
  • [2023-09-13 22:24:06]
  • 提交

answer

//#pragma GCC optimize("Ofast", "unroll-loops")
//#pragma GCC target("sse", "sse2", "sse3", "ssse3", "sse4")
#ifdef LOCAL
#include <iostream>
#include <cmath>
#include <algorithm>
#include <stdio.h>
#include <cstdint>
#include <cstring>
#include <string>
#include <cstdlib>
#include <vector>
#include <bitset>
#include <map>
#include <queue>
#include <ctime>
#include <stack>
#include <set>
#include <list>
#include <random>
#include <deque>
#include <functional>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <complex>
#include <numeric>
#include <cassert>
#include <array>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <thread>
#else
#include <bits/stdc++.h>
#endif

#define all(a) a.begin(),a.end()
#define len(a) (int)(a.size())
#define mp make_pair
#define pb push_back
#define fir first
#define sec second
#define fi first
#define se second

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;

template<typename T>
inline bool umin(T &a, T b) {
    if (b < a) {
        a = b;
        return true;
    }
    return false;
}

template<typename T>
inline bool umax(T &a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

#ifdef LOCAL
#define D for (bool _FLAG = true; _FLAG; _FLAG = false)
#define LOG(...) print(#__VA_ARGS__" ::", __VA_ARGS__) << endl
template <class ...Ts> auto &print(Ts ...ts) { return ((cerr << ts << " "), ...); }
#else
#define D while (false)
#define LOG(...)
#endif // LOCAL

const int max_n = -1, inf = 1000111222;

int powmod (int a, int b, int p) {
    int res = 1;
    while (b)
        if (b & 1)
            res = int (res * 1ll * a % p),  --b;
        else
            a = int (a * 1ll * a % p),  b >>= 1;
    return res;
}

int generator (int p) {
    vector<int> fact;
    int phi = p-1,  n = phi;
    for (int i=2; i*i<=n; ++i)
        if (n % i == 0) {
            fact.push_back (i);
            while (n % i == 0)
                n /= i;
        }
    if (n > 1)
        fact.push_back (n);

    for (int res=2; res<=p; ++res) {
        bool ok = true;
        for (size_t i=0; i<fact.size() && ok; ++i)
            ok &= powmod (res, phi / fact[i], p) != 1;
        if (ok)  return res;
    }
    return -1;
}

const int MOD = 998244353;
struct mint {
    int val;

    mint () : val(0) {}
    mint (int x) {
        if (-MOD <= x && x < MOD) {
            val = x;
        }
        else {
            val = x % MOD;
        }
        if (val < 0) val += MOD;
    }

    mint (ll x) {
        if (-MOD <= x && x < MOD) {
            val = x;
        }
        else {
            val = x % MOD;
        }
        if (val < 0) val += MOD;
    }

    mint (const mint& x) : val(x.val) {}

    constexpr mint& operator = (const mint& x) {
        val = x.val;
        return *this;
    }

    inline mint& operator += (const mint &x) {
        val += x.val;
        if (val >= MOD) {
            val -= MOD;
        }
        return *this;
    }

    inline mint& operator -= (const mint &x) {
        val -= x.val;
        if (val < 0) {
            val += MOD;
        }
        return *this;
    }

    inline mint operator - () const {
        mint tmp(*this);
        if (tmp.val) tmp.val = MOD - tmp.val;
        return tmp;
    }

    inline mint operator + (const mint &x) const {
        return mint(*this) += x;
    }

    inline mint operator - (const mint &x) const {
        return mint(*this) -= x;
    }

    inline mint& operator *= (const mint &x) {
        val = ((ll)val * x.val) % MOD;
        return *this;
    }

    inline mint operator * (const mint &x) const {
        return mint(*this) *= x;
    }

    inline mint binpow (int n) const {
        mint res = 1, tmp = *this;
        for (; n; n >>= 1) {
            if (n & 1) {
                res *= tmp;
            }
            tmp *= tmp;
        }
        return res;
    }

    inline mint inverse () const {
        return binpow(MOD - 2);
    }

    inline mint& operator /= (const mint &x) {
        return *this *= x.inverse();
    }

    inline mint operator / (const mint &x) {
        return mint(*this) *= x.inverse();
    }


    friend ostream& operator << (ostream &os, const mint &x) {
        os << x.val;
        return os;
    }

    friend istream& operator >> (istream &is, mint &x) {
        is >> x.val;
        return is;
    }

    inline bool operator == (const mint &x) const {
        return val == x.val;
    }

    inline bool operator != (const mint &x) const {
        return val != x.val;
    }

    inline bool operator < (const mint &x) const {
        return val < x.val;
    }

    inline bool operator > (const mint &x) const {
        return val > x.val;
    }

    friend string to_string (const mint &x) {
        return to_string(x.val);
    }

};

vector <mint> f = {1}, fi = {1};

inline mint fact (int n) {
    f.reserve(n + 1);
    while (len(f) <= n) {
        f.emplace_back(f.back() * len(f));
    }
    return f[n];
}

inline mint inv_fact (int n) { /// think
    if (len(fi) <= n) {
        fi.resize(n + 1, 0);
        mint val = mint(1) / fact(n);
        for (int i = n; fi[i] == 0; i--) {
            fi[i] = val;
            val *= i;
        }
    }
    return fi[n];
}

inline mint A (int n, int k) {
    if (k < 0 || k > n) return 0;
    return fact(n) * inv_fact(n - k);
}

inline mint C (int n, int k) {
    if (k < 0 || k > n) return 0;
    return A(n, k) * inv_fact(k);
}


typedef vector<mint> poly;
const mint PRIMITIVE_ROOT = 3; /// 119 * 2^23 + 1

vector <int> rev;
vector <mint> roots, inv_roots, cur, ncur;
inline void calc_rev (int n) {
    if (len(rev) == n) return;
    rev.clear();
    int k = 0;
    while ((1 << k) < n) k++;
    rev.resize(n);
    rev[0] = 0;
    int high1 = -1;
    for (int i = 1; i < n; i++) {
        if ((i & (i - 1)) == 0) high1++;
        rev[i] = rev[i ^ (1 << high1)];
        rev[i] |= (1 << (k - high1 - 1));
    }
    mint W = PRIMITIVE_ROOT.binpow((MOD - 1) / n);
    mint W1 = W.inverse();
    roots.clear();
    roots.reserve(25);
    inv_roots.clear();
    inv_roots.reserve(25);
    for (int len = 1; len < n; len <<= 1) {
        roots.pb(W);
        inv_roots.pb(W1);
        W *= W;
        W1 *= W1;
    }
    reverse(all(roots));
    reverse(all(inv_roots));

    cur.clear();
    ncur.clear();
    cur.resize(n);
    ncur.resize(n);
}

poly fft(const poly &as, bool inv = false) {
/// source: https://pastebin.com/3Tnj5mRu
    int n = as.size();
    calc_rev(n);

    for (int i = 0; i < n; i++) cur[i] = as[rev[i]];


    for (int len = 1, l = 0; len < n; len <<= 1, l++) {
        mint w_n = inv ? inv_roots[l] : roots[l], w;
        for (int pdest = 0; pdest < n;) {
            int p1 = pdest;
            w = 1;
            for (int i = 0; i < len; i++) {
                mint val = w * cur[p1 + len];
                ncur[pdest] = cur[p1] + val;
                ncur[pdest + len] = cur[p1] - val;
                pdest++, p1++;
                w *= w_n;
            }
            pdest += len;
        }
        cur.swap(ncur);
    }
    return cur;
}

poly fft_rev(const poly &as) {
    poly res = fft(as, true);
    mint inv = mint(1) / mint(len(as));
    for (int i = 0; i < (int)res.size(); i++) res[i] *= inv;
    //  reverse(res.begin() + 1, res.end());
    return res;
}


inline poly multiply (poly A, poly B) {
    int n = max(len(A), len(B));
    int k = 0;
    while ((1 << k) < n) ++k;
    ++k;
    k = 1 << k;
    A.resize(k);
    B.resize(k);
    A = fft(A);
    B = fft(B);
    for (int i = 0; i < k; i++) {
        A[i] *= B[i];
    }
    return fft_rev(A);
}



inline void test_case () {
    int n, p;
    cin >> n >> p;
    vector <int> a(n);
    bool ok = false;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        if (a[i] == 0) {
            ok = true;
        }
    }
    if (!ok) {
        cout << "1 1\n0\n";
        return;
    }
    int root = generator(p);
    vector <int> b(p);
    for (int i = 1, c = 0; c + 1 < p; c++) {
        b[i] = c;
        i = (i * 1ll * root) % p;
    }
    vector <mint> have(p);
    for (int i = 0; i < n; i++) {
        if (a[i] == 0) {
            continue;
        }
        have[b[a[i]]] = 1;
    }
    int l = 1, r = p;
    while (l < r) {
        int mid = (l + r + 1) >> 1;
        vector <mint> cur(p);
        for (int i = 1; i < mid; i++) {
            cur[p - 1 - b[i]] = 1;
        }
        auto res = multiply(cur, have);
        bool can = false;
        for (int c = 0; c < p - 1; c++) {
            int val = res[c].val + res[c + (p - 1)].val;
            if (val + 1 == mid) {
                can = true;
            }
        }
        if (can) {
            l = mid;
        }
        else {
            r = mid - 1;
        }
    }
    vector <mint> cur(p);
    for (int i = 1; i < r; i++) {
        cur[p - 1 - b[i]] = 1;
    }
    auto res = multiply(cur, have);
    vector <int> ans;
    bool can = false;
    int gg = root;
    for (int c = p - 2; c >= 0; c--) {
        int val = res[c].val + res[c + (p - 1)].val;
        if (val + 1 == r) {
            ans.pb(gg);
        }
        gg = (gg * 1ll * root) % p;
    }
    if (r == 1) {
        ans.pb(0);
    }

    cout << len(ans) << ' ' << r << '\n';
    sort(all(ans));
    for (auto &i : ans) {
        cout << i << ' ';
    }
    cout << '\n';
}


int main() {
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);

    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int t = 1;
    cin >> t;
    for (int test = 1; test <= t; test++) {
        test_case();
    }
}

详细

Test #1:

score: 100
Accepted
time: 1ms
memory: 3420kb

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: 0ms
memory: 3524kb

input:

3
1 2
0
1 2
1
2 2
1 0

output:

2 1
0 2 
1 1
0
1 2
2 

result:

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