結果
| 問題 | No.1901 bitwise xor convolution (characteristic 2) |
| ユーザー |
Taiki0715
|
| 提出日時 | 2026-04-10 22:23:35 |
| 言語 | C++23 (gcc 15.2.0 + boost 1.89.0) |
| 結果 |
AC
|
| 実行時間 | 225 ms / 4,000 ms |
| コード長 | 7,608 bytes |
| 記録 | |
| コンパイル時間 | 1,725 ms |
| コンパイル使用メモリ | 230,860 KB |
| 実行使用メモリ | 54,656 KB |
| 最終ジャッジ日時 | 2026-04-10 22:23:42 |
| 合計ジャッジ時間 | 6,625 ms |
|
ジャッジサーバーID (参考情報) |
judge3_0 / judge1_1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 7 |
コンパイルメッセージ
main.cpp: In member function 'mint mint::operator*(const mint&) const':
main.cpp:275:30: warning: narrowing conversion of '_mm_extract_epi64(m, 0)' from 'long long int' to 'mint::ull' {aka 'long long unsigned int'} [-Wnarrowing]
275 | return {_mm_extract_epi64(m,0)};
| ~~~~~~~~~~~~~~~~~^~~~~
ソースコード
#include<stdio.h>
#include<string.h>
#include<string>
#include<cstdlib>
#include<type_traits>
namespace fastio{
static constexpr u_int32_t buf_size=1<<17;
char ibuf[buf_size];
char obuf[buf_size];
u_int32_t pil=0,pir=0,por=0;
struct Pre{
char t[40000];
constexpr Pre(){
for(int i=0;i<10000;i++){
int n=i;
for(int j=3;j>=0;j--){
t[i*4+j]='0'+n%10;
n/=10;
}
}
}
}constexpr pre;
inline void load(){
if(pir-pil<=pil)memcpy(ibuf,ibuf+pil,pir-pil);
else memmove(ibuf,ibuf+pil,pir-pil);
pir=pir-pil+fread(ibuf+pir-pil,1,buf_size-pir+pil,stdin);
pil=0;
}
inline void flush(){
fwrite(obuf,1,por,stdout);
por=0;
}
inline void rd(char&c){c=ibuf[pil++];}
inline void rd(std::string&s){
char c;
s.clear();
if(pil==pir)load();
rd(c);
if(pil==pir)load();
while(!std::isspace(c)){
s+=c;
rd(c);
if(pil==pir)load();
}
}
inline void rd(__int128_t&x){
if(pil+50>pir)load();
char c;
do rd(c); while(c<'-');
bool neg=false;
if(c=='-'){
neg=true;
rd(c);
}
x=0;
while(c>='0'){
x=x*10+(c&15);
rd(c);
}
if(neg)x=-x;
}
template<typename T>
inline void rd(T&x){
if(pil+32>pir)load();
char c;
do rd(c); while(c<'-');
bool neg=false;
if constexpr(std::is_signed_v<T>){
if(c=='-'){
neg=true;
rd(c);
}
}
x=0;
while(c>='0'){
x=x*10+(c&15);
rd(c);
}
if constexpr(std::is_signed_v<T>){
if(neg)x=-x;
}
}
inline void wt(char x){obuf[por++]=x;}
template<typename T,std::enable_if_t<std::is_integral_v<T>,std::nullptr_t> =nullptr>
inline void wt(T x){
if(por+32>buf_size)flush();
if(x==0){
wt('0');
return;
}
if constexpr(std::is_signed_v<T>){
if(x<0){
wt('-');
x=-x;
}
}
if(x>=10000000000000000){
u_int32_t r1=x%100000000;
u_int64_t q1=x/100000000;
u_int32_t r2=q1%100000000;
u_int32_t q2=q1/100000000;
u_int32_t n1=r1%10000,n2=r1/10000,n3=r2%10000,n4=r2/10000;
if(x>=1000000000000000000){
if constexpr(std::is_unsigned_v<T>){
if(x>=10000000000000000000ull){
obuf[por++]='1';
}
}
memcpy(obuf+por,pre.t+(q2<<2)+1,3);
memcpy(obuf+por+3,pre.t+(n4<<2),4);
memcpy(obuf+por+7,pre.t+(n3<<2),4);
memcpy(obuf+por+11,pre.t+(n2<<2),4);
memcpy(obuf+por+15,pre.t+(n1<<2),4);
por+=19;
}
else if(x>=100000000000000000){
u_int32_t q3=(q2*205)>>11;
u_int32_t r3=q2-q3*10;
obuf[por]='0'+q3;
obuf[por+1]='0'+r3;
memcpy(obuf+por+2,pre.t+(n4<<2),4);
memcpy(obuf+por+6,pre.t+(n3<<2),4);
memcpy(obuf+por+10,pre.t+(n2<<2),4);
memcpy(obuf+por+14,pre.t+(n1<<2),4);
por+=18;
}
else{
obuf[por]='0'+q2;
memcpy(obuf+por+1,pre.t+(n4<<2),4);
memcpy(obuf+por+5,pre.t+(n3<<2),4);
memcpy(obuf+por+9,pre.t+(n2<<2),4);
memcpy(obuf+por+13,pre.t+(n1<<2),4);
por+=17;
}
}
else{
static char buf[12];
int i=8;
while(x>=10000){
memcpy(buf+i,pre.t+((x%10000)<<2),4);
x/=10000;
i-=4;
}
if(x<100){
if(x<10)obuf[por++]='0'+x;
else{
obuf[por]='0'+x/10;
obuf[por+1]='0'+x%10;
por+=2;
}
}
else{
if(x<1000){
memcpy(obuf+por,pre.t+(x<<2)+1,3);
por+=3;
}
else{
memcpy(obuf+por,pre.t+(x<<2),4);
por+=4;
}
}
memcpy(obuf+por,buf+i+4,8-i);
por+=8-i;
}
}
inline void wt(const std::string&s){
int sz=s.size();
if(por+sz>buf_size)flush();
memcpy(obuf+por,s.c_str(),sz);
por+=sz;
}
inline void wt(__int128_t x){
if(por+50>buf_size)flush();
if(x==0){
wt('0');
return;
}
if(x<0){
wt('-');
x=-x;
}
static constexpr __int128_t b=10000000000000000000ull;
if(x>=b){
wt<unsigned long long>(x/b);
unsigned long long y=x%b;
memcpy(obuf+por,pre.t+((y/10000000000000000)<<2)+1,3);
memcpy(obuf+por+3,pre.t+((y/1000000000000%10000)<<2),4);
memcpy(obuf+por+7,pre.t+((y/100000000%10000)<<2),4);
memcpy(obuf+por+11,pre.t+((y/10000%10000)<<2),4);
memcpy(obuf+por+15,pre.t+((y%10000)<<2),4);
por+=19;
}
else wt<unsigned long long>(x);
}
struct Dummy{
Dummy(){std::atexit(flush);}
}dummy;
}
using fastio::rd;
using fastio::wt;
#include<vector>
#include<cassert>
#include<limits>
#include<concepts>
template<typename T>
constexpr std::enable_if_t<std::numeric_limits<T>::digits<=32,int>msb(T n){return n==0?-1:31-__builtin_clz(n);}
template<typename T>
constexpr std::enable_if_t<(std::numeric_limits<T>::digits>32),int>msb(T n){return n==0?-1:63-__builtin_clzll(n);}
template<typename T>
constexpr std::enable_if_t<std::numeric_limits<T>::digits<=32,int>lsb(T n){return n==0?-1:__builtin_ctz(n);}
template<typename T>
constexpr std::enable_if_t<(std::numeric_limits<T>::digits>32),int>lsb(T n){return n==0?-1:__builtin_ctzll(n);}
template<typename T>
constexpr std::enable_if_t<std::is_integral_v<T>,T>floor_pow2(T n){return n==0?0:T(1)<<msb(n);}
template<typename T>
constexpr std::enable_if_t<std::is_integral_v<T>,T>ceil_pow2(T n){return n<=1?1:T(1)<<(msb(n-1)+1);}
template<std::integral T>
constexpr T safe_div(T a,T b){return a/b-(a%b&&(a^b)<0);}
template<std::integral T>
constexpr T safe_ceil(T a,T b){return a/b+(a%b&&(a^b)>0);}
template<typename T>
std::vector<T>arbitrary_xor_convolution(std::vector<T>f,std::vector<T>g){
assert(f.size()==g.size());
int n=f.size();
int lg=msb(n);
assert(1<<lg==n);
for(int i=0;i<lg;i++)for(int j=0;j<n;j++)if(j>>i&1){
f[j^(1<<i)]=f[j^(1<<i)]-f[j];
g[j^(1<<i)]=g[j^(1<<i)]-g[j];
}
std::vector<std::vector<T>>a(n,std::vector<T>(lg+1)),b(n,std::vector<T>(lg+1));
for(int i=0;i<n;i++){
a[i][std::popcount<unsigned>(i)]=f[i];
b[i][std::popcount<unsigned>(i)]=g[i];
}
for(int i=0;i<lg;i++)for(int j=0;j<n;j++)if(j>>i&1){
for(int k=0;k<=lg;k++){
a[j][k]=a[j][k]+a[j^(1<<i)][k];
b[j][k]=b[j][k]+b[j^(1<<i)][k];
}
}
std::vector<T>h(lg*2+1);
for(int i=0;i<n;i++){
std::fill(h.begin(),h.end(),T());
for(int j=0;j<=lg;j++)for(int k=0;k<=lg;k++)h[j+k]=h[j+k]+a[i][j]*b[i][k];
for(int j=lg*2-1;j>=0;j--)h[j]=h[j]+h[j+1]+h[j+1];
std::copy(h.begin(),h.begin()+lg+1,a[i].begin());
}
for(int i=0;i<lg;i++)for(int j=0;j<n;j++)if(j>>i&1){
for(int k=0;k<=lg;k++){
a[j][k]=a[j][k]-a[j^(1<<i)][k];
}
}
for(int i=0;i<n;i++)f[i]=a[i][std::popcount<unsigned>(i)];
for(int i=0;i<lg;i++)for(int j=0;j<n;j++)if(j>>i&1)f[j^(1<<i)]=f[j^(1<<i)]+f[j];
return f;
}
#include<immintrin.h>
struct mint{
using ull=unsigned long long;
ull x;
mint operator+(const mint&rhs)const{
return {x^rhs.x};
}
mint operator-(const mint&rhs)const{
return {x^rhs.x};
}
__attribute__((target("pclmul,sse4.2")))
mint operator*(const mint&rhs)const{
__m128i m=_mm_clmulepi64_si128(_mm_set_epi64x(0,x),_mm_set_epi64x(0,rhs.x),0);
return {_mm_extract_epi64(m,0)};
}
};
int main(){
int n;
rd(n);
std::vector<mint>a(1<<n),b(1<<n);
char c;
for(int i=0;i<(1<<n);i++){
for(int j=0;j<32;j++){
rd(c);
if(c=='1')a[i].x|=1ull<<j;
rd(c);
}
if(fastio::pil+100>fastio::pir)fastio::load();
}
for(int i=0;i<(1<<n);i++){
for(int j=0;j<32;j++){
rd(c);
if(c=='1')b[i].x|=1ull<<j;
rd(c);
}
if(fastio::pil+100>fastio::pir)fastio::load();
}
a=arbitrary_xor_convolution(a,b);
for(int i=0;i<(1<<n);i++){
for(int j=0;j<63;j++){
if(a[i].x>>j&1)wt('1');
else wt('0');
wt(" \n"[j+1==63]);
}
if(fastio::por+130>fastio::buf_size)fastio::flush();
}
}
Taiki0715