結果

問題 No.1901 bitwise xor convolution (characteristic 2)
ユーザー shobonvipshobonvip
提出日時 2023-04-03 20:38:32
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 1,182 ms / 4,000 ms
コード長 2,136 bytes
コンパイル時間 3,506 ms
コンパイル使用メモリ 215,372 KB
実行使用メモリ 64,168 KB
最終ジャッジ日時 2023-10-25 06:46:31
合計ジャッジ時間 12,122 ms
ジャッジサーバーID
(参考情報)
judge15 / judge14
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,348 KB
testcase_01 AC 2 ms
4,348 KB
testcase_02 AC 2 ms
4,348 KB
testcase_03 AC 1 ms
4,348 KB
testcase_04 AC 2 ms
4,348 KB
testcase_05 AC 2 ms
4,348 KB
testcase_06 AC 2 ms
4,348 KB
testcase_07 AC 1,181 ms
64,168 KB
testcase_08 AC 1,182 ms
64,168 KB
testcase_09 AC 1,177 ms
64,168 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#pragma GCC target("pclmul", "sse2", "sse4.1")
#include<emmintrin.h>
#include<smmintrin.h>
#include<wmmintrin.h>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

ll clmul(ll x, ll 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);
}

vector<ll> subset_convolution(int n, vector<ll> a, vector<ll> b){
	
	int s = n+1;
	int L = 1<<n;
	vector<int> pops(L);
	for (int i=0; i<L; i++){
		pops[i] = __builtin_popcount(i);
	}

	vector<ll> ta(s*L), tb(s*L);
	for (int i=0; i<L; i++){
		ta[i*s+pops[i]] = a[i];
		tb[i*s+pops[i]] = b[i];
	}

	int j, jj;
	for (int i=0; i<n; i++){
		j = 0;
		for (int x=0; x<L/2; x++){
			if (!(j>>i&1)) j |= 1<<i;
			jj = j^(1<<i);
			for (int t=0; t<n+1; t++){
				ta[j*s+t] ^= ta[jj*s+t];
				tb[j*s+t] ^= tb[jj*s+t];
			}
			j++;
		}
	}

	vector<ll> tc(s*L);
	int si, sit;
	for (int i=0; i<L; i++){
		si = i*s;
		for (int t=0; t<n+1; t++){
			sit = si+t;
			for (int j=0; j<n-t+1; j++){
				tc[sit+j] ^= clmul(ta[sit], tb[si+j]);
			}
		}
	}

	for (int i=0; i<n; i++){
		j = 0;
		for (int x=0; x<L/2; x++){
			if (!(j>>i&1)) j |= 1<<i;
			jj = j^(1<<i);
			for (int t=0; t<n+1; t++){
				tc[j*s+t] ^= tc[jj*s+t];
			}
			j++;
		}
	}

	vector<ll> c(L);
	for (int i=0; i<L; i++){
		c[i] = tc[i*s+pops[i]];
	}

	return c;

}



int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	
	int n; cin >> n;
	vector<ll> a(1<<n);
	vector<ll> b(1<<n);
	
	for (int i=0; i<1<<n; i++){
		for (int j=0; j<32; j++){
			ll x; cin >> x;
			a[i] |= x<<j;
		}
	}

	for (int i=0; i<1<<n; i++){
		for (int j=0; j<32; j++){
			ll x; cin >> x;
			b[i] |= x<<j;
		}
	}

	for (int i=0; i<n; i++){
		for (int j=0; j<1<<n; j++){
			if (j>>i&1){
				a[j^(1<<i)] ^= a[j];
				b[j^(1<<i)] ^= b[j];
			}
		}
	}

	vector<ll> c = subset_convolution(n, a, b);

	
	for (int i=0; i<n; i++){
		for (int j=0; j<1<<n; j++){
			if (j>>i&1){
				c[j^(1<<i)] ^= c[j];
			}
		}
	}

	for (int i=0; i<1<<n; i++){
		for (int j=0; j<63; j++){
			cout << (c[i]>>j&1);
			if (j==62) cout << "\n";
			else cout << " ";
		}
	}
}
0