結果
| 問題 | No.1901 bitwise xor convolution (characteristic 2) |
| ユーザー |
noshi91
|
| 提出日時 | 2022-04-07 03:45:46 |
| 言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 1,077 ms / 4,000 ms |
| コード長 | 2,557 bytes |
| コンパイル時間 | 3,087 ms |
| コンパイル使用メモリ | 108,396 KB |
| 最終ジャッジ日時 | 2025-01-28 15:35:20 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 7 |
ソースコード
#pragma GCC target("pclmul", "sse2", "sse4.1")
#include <emmintrin.h>
#include <smmintrin.h>
#include <wmmintrin.h>
__int64_t clmul(__int64_t x, __int64_t 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>
using i64 = __int64_t;
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;
}
noshi91