QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#111530 | #6399. Classic: Classical Problem | Tobo | WA | 2ms | 3716kb | C++20 | 5.7kb | 2023-06-07 15:14:29 | 2023-06-07 15:14:33 |
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_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'