QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#456418 | #6549. Two Missing Numbers | pandapythoner | 0 | 1ms | 3772kb | C++23 | 5.5kb | 2024-06-27 21:55:07 | 2024-06-27 21:55:09 |
answer
#pragma GCC optimize("Ofast,unroll-loops,fast-math")
#include <bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define ulll __uint128_t
#define ll long long
#define flt double
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define rep(i, n) for(int i = 0; i < n; i += 1)
const ll inf = 1e18;
mt19937 rnd(234);
ostream& operator<<(ostream& out, ulll x) {
out << (ull)x;
return out;
}
istream& operator>>(istream& in, ulll& x) {
ull a;
in >> a;
x = a;
return in;
}
ulll lg(ulll x) {
assert(x != 0);
ull s = (x >> 64);
if (s > 0) {
return 64 + __lg(s);
}
ull f = x & ((((ulll)1) << 64) - 1);
return __lg(f);
}
ulll mul(ulll a, ulll b) {
if (a == 0 or b == 0) {
return 0;
}
ulll c = 0;
int k = lg(a);
rep(i, k + 1) if ((a >> i) & 1) c ^= (b << i);
return c;
}
ulll mod(ulll a, ulll m) {
assert(m != 0);
if (m == 1) {
return 0;
}
if (a == 0) {
return 0;
}
int k = lg(m);
int d = lg(a);
if (d < k) {
return a;
}
ulll c = a;
for (int i = d; i >= k; i -= 1) {
if ((c >> i) & 1) {
c ^= (m << (i - k));
}
}
return c;
}
pair<ulll, ulll> mod_div(ulll a, ulll m) {
assert(m != 0);
if (m == 1) {
return { 0, a };
}
if (a == 0) {
return { 0, 0 };
}
int k = lg(m);
int d = lg(a);
if (d < k) {
return { a, 0 };
}
ulll c = a, e = 0;
for (int i = d; i >= k; i -= 1) {
if ((c >> i) & 1) {
c ^= (m << (i - k));
e |= ((ulll)1 << (i - k));
}
}
return { c, e };
}
ulll mul_mod(ulll a, ulll b, ulll m) {
return mod(mul(a, b), m);
}
ulll gcd(ulll a, ulll b) {
while (a != 0) {
b = mod(b, a);
swap(a, b);
}
return b;
}
array<ulll, 3> gcdex(ulll a, ulll b) {
if (a == 0) {
return { b, 0, 1 };
}
auto [c, d] = mod_div(b, a);
auto [g, x, y] = gcdex(c, a);
return { g, y ^ mul(d, x), x };
}
ulll multiple_square(ulll a, ll cnt, ulll m) {
ulll c = a;
rep(i, cnt) c = mul_mod(c, c, m);
return c;
}
ulll check_irreducible(ulll a) {
assert(a != 0);
int k = lg(a);
assert(k >= 1 and k <= 64);
for (int i = 1; i <= k / 2; i += 1) {
ulll f = multiple_square(2, i, a) ^ 2;
ulll g = gcd(a, f);
if (g != 1) {
return false;
}
}
return true;
}
ulll find_irreducible(int k) {
assert(k >= 1);
auto gen = [&]() {
ulll c = (((ulll)1) << k);
rep(i, k) if (rnd() % 2) c += (((ulll)1) << i);
return c;
};
while (1) {
ulll x = gen();
if (check_irreducible(x)) {
return x;
}
}
}
const int base = 64;
const ulll m = find_irreducible(base);
ulll inv(ulll a) {
assert(a != 0);
auto [g, x, y] = gcdex(a, m);
assert(g == 1);
return mod(x, m);
}
pair<ulll, ulll> find_roots(ulll a, ulll b) {
// finds roots of x^2 + a*x + b = 0
// assumes, that there is exactly two different nonzero roots
ulll power = ((((ulll)1) << base) - 1) / 3;
auto mul_poly = [&](ulll p0, ulll p1, ulll q0, ulll q1) -> pair<ulll, ulll> {
ulll t0 = mul_mod(p0, q0, m);
assert(t0 < m);
ulll t1 = mul_mod(p1, q0, m) ^ mul_mod(p0, q1, m);
assert(t1 < m);
ulll c = mul_mod(p1, q1, m);
assert(c < m);
t1 ^= mul_mod(c, a, m);
assert(t1 < m);
t0 ^= mul_mod(c, b, m);
assert(t0 < m);
return { t0, t1 };
};
function<pair<ulll, ulll>(ulll, ulll, ulll)> bin_pow_poly;
bin_pow_poly = [&](ulll p, ulll q, ulll n) -> pair<ulll, ulll> {
if (n == 0) {
return { 1, 0 };
}
auto [f0, f1] = bin_pow_poly(p, q, n / 2);
assert(f0 < m and f1 < m);
auto [a0, a1] = mul_poly(f0, f1, f0, f1);
if (n & 1) {
return mul_poly(a0, a1, p, q);
}
return { a0, a1 };
};
while (1) {
ulll r = mul_mod(rnd(), rnd(), m);
auto [a0, a1] = bin_pow_poly(r, 1, power);
a0 ^= 1;
if (a1 != 0) {
ulll first_root = mul_mod(a0, inv(a1), m);
ulll second_root = a ^ first_root;
if (mul_mod(first_root, second_root, m) == b) {
return { first_root, second_root };
}
}
}
}
ulll cube(ulll a) {
return mul_mod(mul_mod(a, a, m), a, m);
}
int32_t main() {
if (1) {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
}
int q, n;
cin >> q >> n;
ulll a = 0, b = 0;
if (q == 2) {
cin >> a >> b;
}
auto lo = b;
ulll hi = 0;
ulll mask = ((ulll)1 << 64) - 1;
rep(i, n) {
ulll x;
cin >> x;
a ^= x;
ulll f = mul(x, x);
lo ^= mul(f & mask, x);
ulll q = mul(f >> 64, x);
lo ^= ((q & mask) << 64);
hi ^= (q >> 64);
}
b = mod(lo ^ (mod(hi >> 64, m) >> 64), m);
if (q == 2) {
ulll sum = a;
ulll prod = mul_mod(cube(a) ^ b, inv(a), m);
auto [x, y] = find_roots(sum, prod);
cout << x << " " << y << "\n";
} else {
cout << a << " " << b << "\n";
}
return 0;
}
/*
2 2 0 0
100 10
*/
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 3772kb
First Run Input
1 5 5 1 4 4 5
First Run Output
1 1
Second Run Input
2 3 1 1 9 9 3
Second Run Output
1 3
result:
ok correct
Test #2:
score: 100
Accepted
time: 1ms
memory: 3628kb
First Run Input
1 1 0
First Run Output
0 0
Second Run Input
2 1 0 0 1
Second Run Output
1 0
result:
ok correct
Test #3:
score: 0
Stage 2: Program answer Time Limit Exceeded
First Run Input
1 1 10625130587464985929 1167154569617655189
First Run Output
10625130587464985929 10841841726245626780
Second Run Input
2 1 10625130587464985929 10841841726245626780 1167154569617655189