QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#108943#6399. Classic: Classical ProblemberarchegasWA 1ms3456kbC++174.4kb2023-05-27 04:04:322023-05-27 04:04:37

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-05-27 04:04:37]
  • 评测
  • 测评结果:WA
  • 用时:1ms
  • 内存:3456kb
  • [2023-05-27 04:04:32]
  • 提交

answer

#include <bits/stdc++.h>
    
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
    
mt19937 rng((int) chrono::steady_clock::now().time_since_epoch().count());
    
const int MAXN = 2e5 + 5;
const int INF = 2e9;

const ll MOD = (119 << 23) + 1, root = 62; // = 998244353
// For p < 2^30 there is also e.g. 5 << 25, 7 << 26, 479 << 21
// and 483 << 21 (same root). The last two are > 10^9.
#pragma once

int fexp(ll b, ll e) {
    ll ans = 1;
    while (e) {
        if (e&1) ans = (ans * b) % MOD;
        b = (b * b) % MOD;
        e >>= 1;
    }
    return ans;
}

void ntt(vector<ll> &a) {
	int n = a.size(), L = 31 - __builtin_clz(n);
	static vector<ll> rt(2, 1);
	for (static int k = 2, s = 2; k < n; k *= 2, s++) {
		rt.resize(n);
		ll z[] = {1, fexp(root, MOD >> s)};
		for (int i = k; i < 2 * k; i++) rt[i] = rt[i / 2] * z[i & 1] % MOD;
	}
	vector<int> rev(n);
	for(int i = 0; i < n; i++) rev[i] = (rev[i / 2] | (i & 1) << L) / 2;
	for(int i = 0; i < n; i++) if (i < rev[i]) swap(a[i], a[rev[i]]);
	for (int k = 1; k < n; k *= 2) {
		for (int i = 0; i < n; i += 2 * k) {
            for (int j = 0; j < k; j++) {
                ll z = rt[j + k] * a[i + j + k] % MOD, &ai = a[i + j];
                a[i + j + k] = ai - z + (z > ai ? MOD : 0);
                ai += (ai + z >= MOD ? z - MOD : z);
            }
		}
    }
}
vector<ll> conv(const vector<ll> &a, const vector<ll> &b) {
	if (a.empty() || b.empty()) return {};
	int s = a.size() + b.size() - 1, B = 32 - __builtin_clz(s), n = 1 << B;
	int inv = fexp(n, MOD - 2);
	vector<ll> L(a), R(b), out(n);
	L.resize(n), R.resize(n);
	ntt(L), ntt(R);
	for(int i = 0; i < n; i++) out[-i & (n - 1)] = (ll)L[i] * R[i] % MOD * inv % MOD;
	ntt(out);
	return {out.begin(), out.begin() + s};
}

int fexpp(ll b, ll e, int mod) {
    ll ans = 1;
    while (e) {
        if (e&1) ans = (ans * b) % mod;
        b = (b * b) % mod;
        e >>= 1;
    }
    return ans;
}

// finds primitive_root of a prime
int primitive_root(int p) {
    if (p == 2) return 1;
    int phi = p - 1;
    int n = phi;
    vector<int> primes;
    for (int i = 2; i * i <= n; i++) {
        if (n % i == 0) {
            primes.push_back(i);
            while (n % i == 0) 
                n /= i;
        }
    }
    if (n > 1)
        primes.push_back(n);

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

    return -1;
}

int main () {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin >> t;
    while (t--) {
        int n, p;
        cin >> n >> p;
        bool zero = false;
        vector<ll> v(n), id(p);
        for (int i = 0; i < n; i++) {
            cin >> v[i];
            if (!v[i]) zero = true;
        }
        if (!zero) {
            cout << "1 1\n0\n";
            continue;
        }
        if (n == 1) {
            cout << p << " 1\n";
            for (int i = 0; i < p; i++) cout << i << ' ';
            cout << '\n';
            continue;
        }
        int pRoot = primitive_root(p);
        id[1] = 0;
        int x = pRoot;
        for (int i = 1; i < p - 1; i++) {
            id[x] = i;  
            x = (1ll * x * pRoot) % p;
        }
        vector<ll> a(p);
        for (int x : v) {
            if (!x) continue;
            a[id[x]] = 1;
        }
        int l = 0, r = n + 2;
        vector<int> ans;
        while (r > l + 1) {
            int m = (l + r) / 2;
            vector<ll> b(p);
            vector<int> agr;
            for (int i = 1; i < m; i++) b[id[i]] = 1;
            reverse(b.begin(), b.end());
            vector<ll> c = conv(a, b);
            int mx = 0;
            for (int i = p - 1; i < (int)c.size(); i++) {
                if (c[i] == m - 1) {
                    mx = c[i];
                    agr.push_back(fexpp(pRoot, 2 * p - 2 - i, p));
                }
            }
            if (mx == m - 1) {
                l = m;
                ans = agr;
            }
            else r = m;
        }
        cout << ans.size() << ' ' << l << '\n';
        sort(ans.begin(), ans.end());
        for (int x : ans) cout << x << ' ';
        cout << '\n';
    }
    return 0;
}

详细

Test #1:

score: 100
Accepted
time: 0ms
memory: 3452kb

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: 0
Accepted
time: 0ms
memory: 3432kb

input:

3
1 2
0
1 2
1
2 2
1 0

output:

2 1
0 1 
1 1
0
1 2
1 

result:

ok 6 lines

Test #3:

score: -100
Wrong Answer
time: 1ms
memory: 3456kb

input:

7
1 3
0
1 3
1
2 3
1 0
1 3
2
2 3
2 0
2 3
1 2
3 3
0 1 2

output:

3 1
0 1 2 
1 1
0
1 2
1 
1 1
0
1 2
2 
1 1
0
1 3
1 

result:

wrong answer 13th lines differ - expected: '2 3', found: '1 3'