QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#111530#6399. Classic: Classical ProblemToboWA 2ms3716kbC++205.7kb2023-06-07 15:14:292023-06-07 15:14:33

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-06-07 15:14:33]
  • 评测
  • 测评结果:WA
  • 用时:2ms
  • 内存:3716kb
  • [2023-06-07 15:14:29]
  • 提交

answer

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

using i64 = long long;
using Poly = vector<int>;

struct Complex
{
    double x = 0.0;
    double y = 0.0;

    Complex() {}
    Complex(double x, double y) : x(x), y(y) {}
    Complex operator+(const Complex &rhs) const { return Complex(x + rhs.x, y + rhs.y); }
    Complex operator-(const Complex &rhs) const { return Complex(x - rhs.x, y - rhs.y); }
    Complex operator*(const Complex &rhs) const { return Complex(x * rhs.x - y * rhs.y, x * rhs.y + y * rhs.x); }
    Complex conj() const { return Complex(x, -y); }
};

namespace FFT
{
    constexpr double PI = 3.14159265358979323846;
    int binary_upper_bound_in_bits(int w)
    {
        if (w <= 0)
            return 1;
        const int highbit = 31 - __builtin_clz(w);
        return highbit + 1;
    }
    void fft(vector<Complex> &a, int L, int flag)
    {
        // flag == 1 : forward; flag == -1 : inverse.
        // L should be a power of 2.
        int k = binary_upper_bound_in_bits(L - 1);
        vector<Complex> w(L);
        vector<int> rev(L);
        for (int i = 0; i < L; ++i)
        {
            w[i] = Complex(cos(2 * PI / L * i), flag * sin(2 * PI / L * i));
            rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (k - 1));
            if (i < rev[i])
                swap(a[i], a[rev[i]]);
        }
        for (int l = 2; l <= L; l <<= 1)
        {
            int m = l >> 1;
            for (int i = 0; i < L; i += l)
            {
                for (int k = 0; k < m; ++k)
                {
                    Complex t = w[L / l * k] * a[i + k + m];
                    a[i + k + m] = a[i + k] - t;
                    a[i + k] = a[i + k] + t;
                }
            }
        }
        if (flag == -1)
            for (int i = 0; i < L; ++i)
                a[i].x /= L;
    }
}
namespace Polynomial
{
    // basic operator
    int norm(int n) { return 1 << (__lg(n - 1) + 1); }

    // 任意模数多项式乘法
    Poly multiply_p_any(Poly f, Poly g, int p)
    {
        int L = norm((int)f.size() - 1 + (int)g.size() - 1);
        vector<Complex> a(L), b(L), c(L), d(L);
        for (int i = 0; i < f.size(); ++i)
        {
            a[i].x = int(f[i]) >> 15;
            b[i].x = int(f[i]) & 32767;
        }
        for (int i = 0; i < g.size(); ++i)
        {
            c[i].x = int(g[i]) >> 15;
            d[i].x = int(g[i]) & 32767;
        }
        FFT::fft(a, L, 1);
        FFT::fft(b, L, 1);
        FFT::fft(c, L, 1);
        FFT::fft(d, L, 1);
        for (int i = 0; i < L; ++i)
        {
            Complex ta = a[i], tb = b[i], tc = c[i], td = d[i];
            a[i] = ta * tc;
            b[i] = ta * td + tb * tc;
            c[i] = tb * td;
        }
        FFT::fft(a, L, -1);
        FFT::fft(b, L, -1);
        FFT::fft(c, L, -1);
        Poly z((int)f.size() + (int)g.size() - 1);
        for (int i = 0; i < z.size(); ++i)
        {
            z[i] = (((i64)(a[i].x + .5) % p << 30) +
                    ((i64)(b[i].x + .5) % p << 15) +
                    (i64)(c[i].x + .5) % p) %
                   p;
        }
        return z;
    }
}
using namespace Polynomial;

int qpow(int a, int n, int p)
{
    int res = 1;
    while (n)
    {
        if (n & 1)
            res = (i64)res * a % p;
        a = (i64)a * a % p;
        n >>= 1;
    }
    return res;
}
vector<int> get_factors(int a)
{
    vector<int> v;
    for (int i = 1; i * i <= a; ++i)
        if (a % i == 0)
        {
            v.push_back(i);
            if (i * i != a)
                v.push_back(a / i);
        }
    return v;
}
int get_minimum_primitive_root(int m)
{
    int phiM = m - 1;
    auto factors = get_factors(phiM);
    for (int i = 1;; ++i)
    {
        if (gcd(i, m) != 1)
            continue;
        bool ok = true;
        for (auto e : factors)
        {
            if (e != phiM && qpow(i, e, m) == 1)
            {
                ok = false;
                break;
            }
        }
        if (ok)
            return i;
    }
}
void solve()
{
    int n, p;
    cin >> n >> p;
    vector<int> a(n);
    for (int &i : a)
        cin >> i;
    sort(a.begin(), a.end());
    if (a[0] != 0)
    {
        cout << 1 << ' ' << 1 << '\n'
             << 0 << '\n';
        return;
    }
    int g = get_minimum_primitive_root(p);
    vector<int> rev(p + 1);
    for (int i = 0, c = 1; i < p - 1; i++)
    {
        rev[c] = i;
        c = 1ll * c * g % p;
    }
    a.erase(find(a.begin(), a.end(), 0));
    Poly f(p - 1), ret;
    for (auto &x : a)
        f[x = rev[x]] = 1;
    sort(a.begin(), a.end());
    int l = 0, r = p - 1, ans = 0;
    auto check = [&](int x)
    {
        Poly g(p - 1);
        for (int i = 1; i <= x; i++)
            g[rev[i]] = 1;
        for (int i = 0; i < p - 1; i++)
            g.emplace_back(g[i]);
        reverse(g.begin(), g.end());
        ret = multiply_p_any(f, g, 1e9);
        return *max_element(ret.begin(), ret.end()) == x;
    };
    while (l <= r)
    {
        int mid = l + r >> 1;
        if (check(mid))
            ans = mid, l = mid + 1;
        else
            r = mid - 1;
    }
    // assert(check(ans));
    vector<int> vec;
    if (!ans)
        vec.emplace_back(0);
    for (int i = p - 2; i < 2 * p - 3; i++)
        if (ret[i] == ans)
            vec.emplace_back(qpow(g, 3 * p - 4 - i, p));
    cout << vec.size() << ' ' << ans + 1 << '\n';
    sort(vec.begin(), vec.end());
    for (auto x : vec)
        cout << x << ' ';
    cout << '\n';
}

signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    int t = 1;
    cin >> t;
    while (t--)
        solve();
}

详细

Test #1:

score: 0
Wrong Answer
time: 2ms
memory: 3716kb

input:

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

output:

2 2
1 2 
1 1
0
2 2
2 3 

result:

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