QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#456418#6549. Two Missing Numberspandapythoner0 1ms3772kbC++235.5kb2024-06-27 21:55:072024-06-27 21:55:09

Judging History

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

  • [2024-06-27 21:55:09]
  • 评测
  • 测评结果:0
  • 用时:1ms
  • 内存:3772kb
  • [2024-06-27 21:55:07]
  • 提交

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


*/

详细

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

Second Run Output


result: