题解(废话)
这部分作者神志不清的自说自话大家跳过也无妨的qwq……
这题做的人少的吓人,我也是听了f321dd巨佬讲课才来尝试做一做,个人觉得还是很有趣的题qwq。
话说这题网上题解似乎只有不超过 33 篇啊……像我这种菜鸡水平的人没什么题解看就很难受,所以千辛万苦过了这题来记录一下。
话说做这题的时候还有一个有趣的事儿,就是中途用瞪眼法已经再也瞪不出bug的时候,我去偷了一手Picks爷的代码对拍,结果拍出来四五个,手算之后发现错的全是Picks爷的代码qaq,定睛一看发现他在多项式快速幂的时候没有取模,如果 k 比 n 大一些他就裂开了……
顺便给大家送一组第二问的样例吧(应该是满足题目要求的……):
input :
5
1 0 1 0 0
1 0 0 0 0
1
2
1 0 1 0 1
output :
00011
真·题解
不说了上代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define maxn 3000010
#define mod 998244353
#define bin(x) (1<<(x))
#define MS(f,x) memset(f,0,4<<(x))
#define CP(f,g,x) memcpy(f,g,(x)<<2)
#define cn getchar
template<class TY>void read(TY &x){
x=0;int f1=1;char ch=cn();
while(ch<'0'||ch>'9'){if(ch=='-')f1=-1;ch=cn();}
while(ch>='0'&&ch<='9')x=x*10+(ch-'0'),ch=cn(); x*=f1;
}
int n,F[maxn],G[maxn];
int ksm(int x,int y){int re=1;for(;(y&1?re=1ll*re*x%mod:0),y;y>>=1,x=1ll*x*x%mod);return re;}
int w[maxn],inv[maxn];void prep(int lg){int N=bin(lg);
inv[1]=1;for(int i=2;i<=N;i++)inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
for(int i=1,wn;i<N;i<<=1){
w[i]=1;wn=ksm(3,(mod-1)/(i<<1));
for(int j=1;j<i;j++)w[i+j]=1ll*w[i+j-1]*wn%mod;
}
}
void reduce(int &x){x+=x>>31&mod;}
void ntt(int *f,int lg,int type=0){
int limit=bin(lg);if(type)reverse(f+1,f+limit);
for(int i=0,j=0,k;i<limit;i++){if(i<j)swap(f[i],f[j]);k=limit>>1;while((j^=k)<k)k>>=1;}
for(int mid=1,t;mid<limit;mid<<=1)for(int j=0;j<limit;j+=(mid<<1))for(int i=0;i<mid;i++)
{t=1ll*f[j|i|mid]*w[mid|i]%mod;reduce(f[j|i|mid]=f[j|i]-t);reduce(f[j|i]+=t-mod);}
if(type)for(int i=0;i<limit;i++)f[i]=1ll*f[i]*inv[limit]%mod;
}
int A[maxn],B[maxn],C[maxn],D[maxn],E[maxn],Q[maxn],R[maxn];
void NTT(int *f,int *g,int ln,int Mul=2){
int lg=ceil(log2(ln*Mul));ntt(f,lg);ntt(g,lg);
for(int i=0;i<bin(lg);i++)f[i]=1ll*f[i]*g[i]%mod;ntt(f,lg,1);
for(int i=0;i<bin(lg);i++)f[i]&=1;
}
void getsqr(int *f,int ln){
int lg=ceil(log2(2*ln-1));
ntt(f,lg);for(int i=0;i<bin(lg);i++)f[i]=1ll*f[i]*f[i]%mod;
ntt(f,lg,1);for(int i=0;i<bin(lg);i++)f[i]&=1;
}
void getinv(int *f,int *g,int ln){
if(ln==1){g[0]=ksm(f[0],mod-2);return;}getinv(f,g,ln+1>>1);
int lg=ceil(log2(ln<<1));MS(A,lg);MS(B,lg);CP(A,f,ln);CP(B,g,ln);
getsqr(B,ln+1>>1);NTT(B,A,ln);CP(g,B,ln);
}
void getrev(int *f,int *g,int ln){for(int i=0;i<=ln;i++)g[i]=f[ln-i];}
void getdiv(int *f,int *g,int *q,int ln1,int ln2){
int lg=ceil(log2(ln1+1));MS(C,lg);MS(D,lg);MS(E,lg);
getrev(f,C,ln1);getrev(g,D,ln2);for(int i=ln1-ln2+1;i<=ln1;i++)C[i]=D[i]=0;
getinv(D,E,ln1-ln2+1);for(int i=0;i<=ln1-ln2;i++)E[i]&=1;
NTT(C,E,ln1-ln2+1);getrev(C,q,ln1-ln2);
}
void getmod(int *f,int *g,int *q,int *r,int ln1,int ln2){
int lg=ceil(log2(ln1+1));MS(C,lg);MS(D,lg);CP(C,g,ln2+1);CP(D,q,ln1-ln2+1);
NTT(C,D,ln1+1,1);for(int i=0;i<ln2;i++)r[i]=f[i]^C[i];
}
void Modto(int *f,int *g,int ln1,int ln2){
for(int i=0;i<=ln1;i++)f[i]&=1;
getdiv(f,g,Q,ln1,ln2);getmod(f,g,Q,R,ln1,ln2);
for(int i=0;i<=ln1;i++)f[i]=(i<ln2?R[i]:0);
}
int Base[maxn],A1[maxn];
void solve1(){
int ts;read(ts);
int lg=ceil(log2(n<<1));Base[1]=A1[0]=1;
int c1=0,c2=1;
for(;ts;ts>>=1){
if(ts&1){
if((c1+=c2)<n)A1[c1-c2]=0,A1[c1]=1;
else NTT(A1,Base,n),ntt(Base,lg,1),Modto(A1,G,2*n-1,n);
}
if((c2<<=1)<n)Base[c2>>1]=0,Base[c2]=1;
else getsqr(Base,n),Modto(Base,G,2*n-1,n);
}
NTT(F,A1,n);Modto(F,G,2*n-1,n);
for(int i=0;i<n;i++)putchar(F[i]?'1':'0');
}
int Mk[maxn];
void ksm1(int *f,int ts){
for(int i=1;i<=ts;i++)
getsqr(f,n),Modto(f,G,2*n-1,n);
}
void ksm2(int *f,int ts){
int lg=ceil(log2(n<<1));
CP(A1,f,n);ntt(f,lg);
for(int i=1;i<ts;i++){
for(int i=0;i<bin(lg);i++)f[i]=1ll*f[i]*f[i]%mod;
ntt(f,lg,1);Modto(f,G,2*n-1,n);
ntt(f,lg);ntt(A1,lg);for(int i=0;i<bin(lg);i++)A1[i]=1ll*A1[i]*f[i]%mod;
ntt(A1,lg,1);Modto(A1,G,2*n-1,n);
}
for(int i=0;i<bin(lg);i++)f[i]=(i<n?A1[i]:0);
}
void solve2(){
int l;read(l);
for(int i=0;i<n;i++)read(Mk[i]);
ksm1(Mk,n-l);ksm1(F,n-l);ksm2(F,l);
NTT(F,Mk,n);Modto(F,G,2*n-1,n);
for(int i=0;i<n;i++)putchar(F[i]?'1':'0');
}
int main()
{
read(n);prep(ceil(log2(n+1<<1)));
for(int i=0;i<n;i++)read(G[i]);G[n]=1;
for(int i=0;i<n;i++)read(F[i]);
int type;read(type);
if(type==0)solve1();
else solve2();
return 0;
}