QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#111491 | #6399. Classic: Classical Problem | Tobo | WA | 2ms | 3612kb | C++20 | 5.7kb | 2023-06-07 13:17:47 | 2023-06-07 13:17:51 |
Judging History
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_mod_any(Poly f, Poly g, int mod)
{
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) % mod << 30) +
((i64)(b[i].x + .5) % mod << 15) +
(i64)(c[i].x + .5) % mod) %
mod;
}
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;
}
a.erase(find(a.begin(), a.end(), 0));
int g = get_minimum_primitive_root(p);
vector<int> rev(p + 1);
for (int i = 0, tmp = 1; i < p - 1; i++)
{
rev[tmp] = i;
tmp = (i64)tmp * g % p;
}
Poly f(p - 1), res;
for (int i : a)
f[rev[i]] = 1;
int l = 0, r = p - 1, mid;
auto check = [&](int x) -> bool
{
Poly g(p - 1);
for (int i = 1; i <= x; i++)
g[rev[i]] = 1;
reverse(g.begin(), g.end());
for (int i = 0; i < p - 1; i++)
g.push_back(g[i]);
res = multiply_mod_any(f, g, 1e9);
for (int i = p - 2; i < res.size(); i++)
if (res[i] >= x)
return true;
return false;
};
while (l < r)
{
mid = l + r + 1 >> 1;
if (check(mid))
l = mid;
else
r = mid - 1;
}
vector<int> ans;
if (!l)
ans.push_back(0);
for (int i = p - 2; i < 2 * p - 3; i++)
if (res[i] >= l)
ans.push_back(qpow(g, 3 * p - 4 - i, p));
sort(ans.begin(), ans.end());
cout << ans.size() << ' ' << l + 1 << '\n';
for (int i : ans)
cout << i << ' ';
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: 3612kb
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'