Origin Plusmul

    xiaoxiao2025-08-17  8

    子集卷积 有两个长度为 2n 的数列 a0,...,a2n1 b0,...,b2n1 . 求数列 c0,...,c2n1 ,其中 cr= +卷积:

    prap×brp or卷积: p,q[p or q=r]apbq and卷积: p,q[p and q=r]apbq

    不标准或不对的地方欢迎指教:)

    #include <set> #include <ctime> #include <queue> #include <cstdio> #include <bitset> #include <cctype> #include <bitset> #include <cstdlib> #include <cassert> #include <cstring> #include <iostream> #include <algorithm> #define inf (1<<30) #define INF (1ll<<62) #define fi first #define se second #define rep(x,s,t) for(register int x=s,t_=t;x<t_;++x) #define per(x,s,t) for(register int x=t-1,s_=s;x>=s_;--x) #define travel(x) for(int I=last[x],to;I&&(to=e[I].to);I=e[I].nxt) #define prt(x) cout<<#x<<":"<<x<<" " #define prtn(x) cout<<#x<<":"<<x<<endl #define pb(x) push_back(x) #define hash asfmaljkg #define rank asfjhgskjf #define y1 asggnja #define y2 slfvm using namespace std; typedef long long ll; typedef pair<int,int> ii; template<class T>void sc(T &x){ int f=1;char c;x=0; while(c=getchar(),c<48)if(c=='-')f=-1; do x=x*10+(c^48); while(c=getchar(),c>47); x*=f; } template<class T>void nt(T x){ if(!x)return; nt(x/10); putchar(x%10+'0'); } template<class T>void pt(T x){ if(x<0)putchar('-'),x=-x; if(!x)putchar('0'); else nt(x); } template<class T>void ptn(T x){ pt(x);putchar('\n'); } template<class T>void pts(T x){ pt(x);putchar(' '); } template<class T>inline void Max(T &x,T y){if(x<y)x=y;} template<class T>inline void Min(T &x,T y){if(x>y)x=y;} int n; const int maxn=17; const int mod=1e9+7; int a[1<<maxn],b[1<<maxn]; int w[1<<maxn]; inline void mop(int &a,int b){ if((a+=b)>=mod)a-=mod; } void ormul(int *a,int *b,int *c,int n){ static int A[1<<maxn],B[1<<maxn]; rep(i,0,1<<n)A[i]=a[i],B[i]=b[i]; rep(i,0,n)rep(j,1,1<<n) if(j>>i&1){ mop(A[j],A[j^1<<i]); mop(B[j],B[j^1<<i]); } rep(i,0,1<<n)c[i]=A[i]*B[i]; rep(i,0,n)rep(j,1,1<<n) if(j>>i&1)mop(c[j],mod-c[j^1<<i]); }//O(n*2^n) void plusmul(int *a,int *b,int *c,int n){ static int A[maxn+1][1<<maxn]; static int B[maxn+1][1<<maxn]; static int C[maxn+1][1<<maxn]; rep(i,0,n+1)rep(j,0,1<<n) if(w[j]==i) A[i][j]=a[j], B[i][j]=b[j]; else A[i][j]=B[i][j]=0; rep(i,0,n)rep(j,0,1<<n)if(j>>i&1) rep(k,0,w[j]) mop(A[k][j],A[k][j^1<<i]), mop(B[k][j],B[k][j^1<<i]); rep(i,0,1<<n)rep(j,0,n+1){ C[j][i]=0; rep(k,0,j+1) mop(C[j][i],(ll)A[k][i]*B[j-k][i]%mod); } rep(i,0,n)rep(j,0,1<<n)if(j>>i&1) rep(k,0,n+1) mop(C[k][j],mod-C[k][j^1<<i]); rep(i,0,1<<n)c[i]=C[w[i]][i]; }//O(n^2*2^n) void pulsmul(int *a,int *b,int *c,int n){ rep(i,0,1<<n){ c[i]=0; for(int j=i;;j=(j-1)&i){ mop(c[i],(ll)*a[j]*b[i-j]%mod); if(!j)break; } } }//O(3^n) int main(){ // freopen("pro.in","r",stdin); // freopen("chk.out","w",stdout); sc(n); rep(i,1,1<<n)w[i]=w[i>>1]+(i&1); rep(i,0,1<<n)sc(a[i]); rep(i,0,1<<n)sc(b[i]); // plusmul(a,b,a,n);// // ormul(a,b,a,n);// rep(i,0,1<<n){ pt(a[i]); putchar(" \n"[i==t_-1]); } return 0; }
    转载请注明原文地址: https://ju.6miu.com/read-1301804.html
    最新回复(0)