QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#177211 | #6399. Classic: Classical Problem | xaphoenix# | WA | 73ms | 211072kb | C++14 | 4.8kb | 2023-09-12 17:51:31 | 2023-09-12 17:51:31 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pf push_front
#define LC k << 1
#define RC k << 1 | 1
#define IO cin.sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define all(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
#define rep(i, a, n) for (int i = a; i < n; i++)
#define repn(i, a, n) for (int i = a; i <= n; i++)
#define per(i, a, n) for (int i = (n) - 1; i >= a; i--)
#define pern(i, a, n) for (int i = n; i >= a; i--)
typedef long long LL;
typedef long double LD;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<int, LL> PIL;
typedef pair<LL, int> PLI;
typedef pair<double, double> PDD;
typedef pair<ull, ull> PUU;
typedef pair<LL, LL> PLL;
const int N = 410000;
const int M = 1100000;
const int mod = 1e9 + 7;
const int inf = 1e9;
const LL INF = 1e18;
const double eps = 1e-9;
mt19937_64 Rand((unsigned long long)new char);
#define rand Rand
bool valid[N];
int primm, prim[N], nc, pr[N];
void getPrime(int n) {
memset(valid, true, sizeof(valid));
repn(i, 2, n) if (valid[i]) {
prim[++primm] = i;
repn(j, 2, n / i) valid[i * j] = 0;
}
}
LL pow_mod(LL a, LL e, LL p) {
LL res = 1;
for (; e; a = a * a % p, e >>= 1) if (e & 1) res = res * a % mod;
return res;
}
void cal(LL n) {
LL t = n, a;
nc = 0;
for (int i = 1; prim[i] * prim[i] <= n; i++) {
if (n % prim[i] == 0) {
pr[++nc] = prim[i];
while (n % prim[i] == 0) n /= prim[i];
}
}
if (n > 1) pr[++nc] = n;
}
LL findprimitiveroot(LL P){
if (P == 2) return 1;
LL t, g, root;
getPrime(N - 1);
cal(P - 1);
for (g = 2; g < P; g++) {
bool flag = true;
repn(i, 1, nc) {
t = (P - 1) / pr[i];
if (pow_mod(g, t, P) == 1) {
flag = false;
break;
}
}
if (flag) {
root = g;
return root;
}
}
}
#define complex my_complex
const int MAXN = 1 << 21;
const double PI = acos(-1.0);
struct complex {
double r, i;
complex(double _r = 0.0, double _i = 0.0) { r = _r; i = _i;}
complex operator + (const complex &b) { return complex(r + b.r, i + b.i);}
complex operator - (const complex &b) { return complex(r - b.r, i - b.i);}
complex operator * (const complex &b) { return complex(r * b.r - i * b.i, r * b.i + i * b.r);}
complex conj() {return complex(r, -i);}
};
complex W[2][MAXN * 2];
complex fa[MAXN], fb[MAXN];
void init() {
for (int h = 2; h <= MAXN; h <<= 1) {
for (int d = 0; d < h / 2; d++) {
W[0][h + d] = complex(cos(2 * d * PI / h), sin(2 * d * PI / h));
W[1][h + d] = complex(cos(-2 * d * PI / h), sin(-2 * d * PI / h));
}
}
}
void change(complex y[], int len) {
int i, j, k;
for (i = 1, j = len / 2; i < len - 1; i++) {
if (i < j) swap(y[i], y[j]);
k = len / 2;
while (j >= k) j -= k, k /= 2;
if (j < k) j += k;
}
}
void fft(complex y[], int len, int type) {
change(y, len);
for (int h = 2; h <= len; h <<= 1) {
for (int j = 0; j < len; j += h) {
for (int k = j, d = 0; k < j + h / 2; k++, d++) {
complex w;
if (type == 1) w = W[0][h + d];
else w = W[1][h + d];
complex u = y[k], t = w * y[k + h / 2];
y[k] = u + t;
y[k + h / 2] = u - t;
}
}
}
if (type == -1) rep(i, 0, len) y[i].r /= len, y[i].i /= len;
}
int T, n, flag, p, a[N], rt, prj[N], arr[N], b[N], c[N], d[N];
int check(int len) {
int l = 1;
while (l <= 4 * p) l *= 2;
repn(i, 0, p) c[i] = 0;
rep(i, 0, len) c[prj[i + 1]] = 1;
reverse(c, c + p - 1);
rep(i, 0, l) {
if (i <= p + p) fa[i] = complex(b[i], 0);
else fa[i] = complex(0, 0);
if (i <= p) fb[i] = complex(c[i], 0);
else fb[i] = complex(0, 0);
}
fft(fa, l, 1), fft(fb, l, 1);
rep(i, 0, l) fa[i] = fa[i] * fb[i];
fft(fa, l, -1);
int flag = 0;
repn(i, 0, p) d[i] = 0;
rep(i, 0, p - 1) {
int v = (int)(fa[i + p - 2].r + 0.1);
int id1 = (p - 1 - i) % (p - 1);
if (v == len) d[id1] = flag = 1;
}
return flag;
}
int main() {
IO;
init();
cin >> T;
while (T--) {
cin >> n >> p;
flag = 0;
repn(i, 1, n) {
cin >> a[i];
if (a[i] == 0) flag = 1;
}
if (!flag) {
cout << "1 1\n0\n";
continue;
}
rt = findprimitiveroot(p);
prj[1] = 0;
arr[0] = 1;
LL cur = 1;
rep(i, 1, p - 1) cur = cur * rt % p, prj[cur] = i, arr[i] = cur;
repn(i, 0, p + p) b[i] = 0;
repn(i, 1, n) if (a[i] != 0) {
int t = prj[a[i]];
b[t] = b[t + p - 1] = 1;
}
int l = 1, r = p - 1, ans = 0;
while (l <= r) {
int mid = (l + r) / 2;
if (check(mid)) l = mid + 1, ans = mid;
else r = mid - 1;
}
check(ans);
vector<int> v;
rep(i, 0, p - 1) if (d[i] == 1) {
v.pb(arr[i]);
}
cout << v.size() << " " << ans + 1 << "\n";
rep(i, 0, v.size()) cout << v[i] << " \n"[i == SZ(v) - 1];
}
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 73ms
memory: 211072kb
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: 71ms
memory: 208840kb
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'