結果
問題 | No.1901 bitwise xor convolution (characteristic 2) |
ユーザー | suisen |
提出日時 | 2022-04-23 15:25:45 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 4,289 bytes |
コンパイル時間 | 1,201 ms |
コンパイル使用メモリ | 82,260 KB |
実行使用メモリ | 396,944 KB |
最終ジャッジ日時 | 2024-06-25 02:31:12 |
合計ジャッジ時間 | 7,876 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,816 KB |
testcase_01 | AC | 2 ms
6,940 KB |
testcase_02 | AC | 2 ms
6,940 KB |
testcase_03 | AC | 2 ms
6,940 KB |
testcase_04 | AC | 2 ms
6,940 KB |
testcase_05 | AC | 2 ms
6,940 KB |
testcase_06 | AC | 2 ms
6,940 KB |
testcase_07 | TLE | - |
testcase_08 | -- | - |
testcase_09 | -- | - |
コンパイルメッセージ
main.cpp: In function 'int main()': main.cpp:150:57: warning: narrowing conversion of 'n' from 'std::size_t' {aka 'long unsigned int'} to 'uint32_t' {aka 'unsigned int'} [-Wnarrowing] 150 | std::cout << (int64_t(c[i][j] / FacInt { 1, n }) & 1) << ' '; | ^
ソースコード
#pragma GCC target("avx2") #pragma GCC optimize("O3") #pragma GCC optimize("unroll-loops") #include <array> #include <cassert> #include <iostream> #include <vector> struct FacInt { int64_t p; uint32_t q; FacInt() = default; FacInt(int64_t p, uint32_t q) : p(p), q(q) {} FacInt(int64_t v) { if (v) { q = __builtin_ctzll(v); p = v >> q; } else { p = q = 0; } } friend FacInt operator-(const FacInt& x) { return FacInt{ -x.p, x.q }; } friend FacInt operator+(const FacInt& x, const FacInt& y) { if (x.p == 0) return y; if (y.p == 0) return x; uint32_t q = std::min(x.q, y.q); int64_t px = x.p << (x.q - q); int64_t py = y.p << (y.q - q); FacInt res = px + py; res.q += q; return res; } friend FacInt operator-(const FacInt& x, const FacInt& y) { return x + (-y); } friend FacInt operator*(const FacInt& x, const FacInt& y) { if (x.p == 0) return x; if (y.p == 0) return y; return FacInt{ x.p * y.p, x.q + y.q }; } friend FacInt operator/(const FacInt& x, const FacInt& y) { assert(y.p); if (x.p == 0) return x; assert(x.p % y.p == 0 and x.q >= y.q); return FacInt{ x.p / y.p, x.q - y.q }; } operator int64_t() { return p << q; } }; struct FacIntPoly : std::array<FacInt, 63> { FacIntPoly() { for (std::size_t i = 0; i < 63; ++i) { (*this)[i] = FacInt{0}; } } friend FacIntPoly operator+(const FacIntPoly &x, const FacIntPoly &y) { FacIntPoly z; for (std::size_t i = 0; i < 63; ++i) { z[i] = x[i] + y[i]; } return z; } friend FacIntPoly operator-(const FacIntPoly &x, const FacIntPoly &y) { FacIntPoly z; for (std::size_t i = 0; i < 63; ++i) { z[i] = x[i] - y[i]; } return z; } friend FacIntPoly operator*(const FacIntPoly &x, const FacIntPoly &y) { FacIntPoly z; for (std::size_t i = 0; i < 32; ++i) for (std::size_t j = 0; j < 32; ++j) { z[i + j] = z[i + j] + x[i] * y[j]; } return z; } }; void unit_walsh_hadamard_transform(FacIntPoly& x0, FacIntPoly& x1) { FacIntPoly y0 = x0, y1 = x1; x0 = y0 + y1; // 1, 1 x1 = y0 - y1; // 1, -1 } template <typename UnitTransform, typename ReferenceGetter, std::size_t... Seq> void unit_transform(UnitTransform transform, ReferenceGetter ref_getter, std::index_sequence<Seq...>) { transform(ref_getter(Seq)...); } void walsh_hadamard(std::vector<FacIntPoly>& x) { const std::size_t n = x.size(); for (std::size_t block = 1; block < n; block *= 2) { for (std::size_t l = 0; l < n; l += 2 * block) { for (std::size_t offset = l; offset < l + block; ++offset) { const auto ref_getter = [&](std::size_t i) -> FacIntPoly& { return x[offset + i * block]; }; unit_transform(unit_walsh_hadamard_transform, ref_getter, std::make_index_sequence<2>()); } } } } int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); std::size_t n; std::cin >> n; std::vector<FacIntPoly> a(1 << n), b(1 << n), c(1 << n); for (std::size_t i = 0; i < 1U << n; ++i) { for (std::size_t j = 0; j < 32; ++j) { std::size_t bit; std::cin >> bit; a[i][j] = bit; } for (std::size_t j = 32; j < 63; ++j) { a[i][j] = 0; } } for (std::size_t i = 0; i < 1U << n; ++i) { for (std::size_t j = 0; j < 32; ++j) { std::size_t bit; std::cin >> bit; b[i][j] = bit; } for (std::size_t j = 32; j < 63; ++j) { b[i][j] = 0; } } walsh_hadamard(a); walsh_hadamard(b); for (std::size_t i = 0; i < 1U << n; ++i) { c[i] = a[i] * b[i]; } walsh_hadamard(c); for (std::size_t i = 0; i < 1U << n; ++i) { for (std::size_t j = 0; j < 63; ++j) { std::cout << (int64_t(c[i][j] / FacInt { 1, n }) & 1) << ' '; } std::cout << '\n'; } return 0; }