結果
問題 | No.1901 bitwise xor convolution (characteristic 2) |
ユーザー | noshi91 |
提出日時 | 2022-04-07 03:28:42 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 1,107 ms / 4,000 ms |
コード長 | 2,541 bytes |
コンパイル時間 | 1,103 ms |
コンパイル使用メモリ | 85,748 KB |
実行使用メモリ | 64,700 KB |
最終ジャッジ日時 | 2024-06-01 03:32:29 |
合計ジャッジ時間 | 8,522 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,812 KB |
testcase_01 | AC | 2 ms
6,940 KB |
testcase_02 | AC | 2 ms
6,944 KB |
testcase_03 | AC | 2 ms
6,940 KB |
testcase_04 | AC | 2 ms
6,944 KB |
testcase_05 | AC | 2 ms
6,940 KB |
testcase_06 | AC | 2 ms
6,944 KB |
testcase_07 | AC | 1,107 ms
64,660 KB |
testcase_08 | AC | 1,103 ms
64,648 KB |
testcase_09 | AC | 1,101 ms
64,700 KB |
ソースコード
#pragma GCC target("sse2", "pclmul", "sse4.1") #include <emmintrin.h> #include <smmintrin.h> #include <wmmintrin.h> using i64 = __int64_t; i64 clmul(i64 x, i64 y) { __m128i x_ = _mm_set_epi64x(0, x); __m128i y_ = _mm_set_epi64x(0, y); __m128i z_ = _mm_clmulepi64_si128(x_, y_, 0); return _mm_extract_epi64(z_, 0); } #include <array> #include <iostream> #include <vector> static constexpr int n_max = 18; using poly = std::array<i64, n_max + 1>; static constexpr int W = 31; template <class F, class T> void bitwise_transform(F f, std::vector<T> &a) { const int n = a.size(); for (int w = 1; w < n; w *= 2) { for (int k = 0; k < n; k += w * 2) { for (int i = 0; i < w; i++) { f(a[k + i], a[k + w + i]); } } } } std::vector<poly> rank(const std::vector<i64> &a) { const int n = a.size(); std::vector<poly> b(n); for (int i = 0; i < n; i++) { int cnt = 0; for (int k = 0; k < n_max; k++) { if (i >> k & 1) { cnt++; } } b[i][cnt] = a[i]; } return b; } std::vector<i64> unrank(const std::vector<poly> &a) { const int n = a.size(); std::vector<i64> b(n); for (int i = 0; i < n; i++) { int cnt = 0; for (int k = 0; k < n_max; k++) { if (i >> k & 1) { cnt++; } } b[i] = a[i][cnt]; } return b; } int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int n; std::cin >> n; std::vector<i64> A(1 << n, 0), B(1 << n, 0); for (i64 &e : A) { for (int i = 0; i <= W; i++) { int a; std::cin >> a; e |= i64(a) << i; } } for (i64 &e : B) { for (int i = 0; i <= W; i++) { int b; std::cin >> b; e |= i64(b) << i; } } const auto add_sub = [](i64 &l, i64 &r) { l ^= r; }; const auto addp_sup = [](auto &l, auto &r) { for (int i = 0; i <= n_max; i++) { r[i] ^= l[i]; } }; bitwise_transform(add_sub, A); bitwise_transform(add_sub, B); auto rA = rank(A); auto rB = rank(B); bitwise_transform(addp_sup, rA); bitwise_transform(addp_sup, rB); std::vector<poly> rC(1 << n); for (int i = 0; i < (1 << n); i++) { for (int j = 0; j <= n_max; j++) { for (int k = 0; k <= n_max - j; k++) { rC[i][j + k] ^= clmul(rA[i][j], rB[i][k]); } } } bitwise_transform(addp_sup, rC); auto c = unrank(rC); bitwise_transform(add_sub, c); for (const i64 &e : c) { for (int i = 0; i <= W * 2; i++) { std::cout << (e >> i & 1) << " \n"[i == W * 2]; } } return 0; }