zoukankan      html  css  js  c++  java
  • [LUOGU 4717] 快速沃尔什变换

    题目传送-Luogu4717

    题意:

    给你(A),(B),求$$C_i=sum_{joplus k=i}A_j*B_k $$
    (oplus)包括(or),(and),(xor)
    (lenle 2^{17})

    题解:

    裸的(FWT),总结先留坑

    过程:

    一切顺利

    代码:

    const int BIT=17,N=1<<BIT;
    const ll P=998244353;
    int n;
    ll A[N],B[N];
    ll a[N],b[N],c[N];
    inline ll Add(ll x,ll y) {x+=y; return x>=P ? x-P : x;}
    inline ll Div(ll x) {return x&1 ? (x+P)>>1 : x>>1;}
    namespace XOR {
    	inline void FWT(ll *a,int n,int type) {
    		for(int haf=1;haf<n;haf<<=1)
    			for(int st=0,d=haf<<1;st<n;st+=d)
    				for(int i=0;i<haf;i++) {
    					int x=a[st+i],y=a[st+haf+i];
    					if(type) {
    						a[st+i]=Add(x,y);
    						a[st+haf+i]=Add(x,-y+P);
    					} else {	
    						a[st+i]=Div(Add(x,y));
    						a[st+haf+i]=Div(Add(x,-y+P));
    					}
    				}
    	}
    }
    namespace OR {
    	inline void FWT(ll *a,int n,int type) {
    		for(int haf=1;haf<n;haf<<=1)
    			for(int st=0,d=haf<<1;st<n;st+=d)
    				for(int i=0;i<haf;i++) {
    					a[st+haf+i]+=a[st+i]*type+P;
    					if(a[st+haf+i]>=P) a[st+haf+i]-=P;
    					if(a[st+haf+i]>=P) a[st+haf+i]-=P;
    				}
    	}
    }
    namespace AND {
    	inline void FWT(ll *a,int n,int type) {
    		for(int haf=1;haf<n;haf<<=1)
    			for(int st=0,d=haf<<1;st<n;st+=d)
    				for(int i=0;i<haf;i++) {
    					a[st+i]+=a[st+haf+i]*type+P;
    					if(a[st+i]>=P) a[st+i]-=P;
    					if(a[st+i]>=P) a[st+i]-=P;
    				}
    	}
    }
    
    signed main() {
    	read(n); n=1<<n;
    	for(int i=0;i<n;i++) read(A[i]);
    	for(int i=0;i<n;i++) read(B[i]);
    
    	memcpy(a,A,sizeof(A)); memcpy(b,B,sizeof(B));
    	OR::FWT(a,n,1),OR::FWT(b,n,1);
    	for(int i=0;i<n;i++) c[i]=a[i]*b[i]%P;
    	OR::FWT(c,n,-1); for(int i=0;i<n;i++) printf("%lld ",c[i]); puts("");
    
    	memcpy(a,A,sizeof(A)); memcpy(b,B,sizeof(B));
    	AND::FWT(a,n,1),AND::FWT(b,n,1);
    	for(int i=0;i<n;i++) c[i]=a[i]*b[i]%P;
    	AND::FWT(c,n,-1); for(int i=0;i<n;i++) printf("%lld ",c[i]); puts(""); 
    
    	memcpy(a,A,sizeof(A)); memcpy(b,B,sizeof(B));
    	XOR::FWT(a,n,1),XOR::FWT(b,n,1);
    	for(int i=0;i<n;i++) c[i]=a[i]*b[i]%P;
    	XOR::FWT(c,n,0); for(int i=0;i<n;i++) printf("%lld ",c[i]); puts("");
    	
    	return 0;
    }
    

    用时:5min

  • 相关阅读:
    枚举8项素数和环
    登录过滤器
    线程调度
    回溯素数环
    centos 6.5 samba简单配置
    区间k大数查询
    Centos安装arm-linux-gcc等交叉工具链
    centos7安装tftp服务器
    八皇后问题
    输出1——n的排列(深度优先搜索)
  • 原文地址:https://www.cnblogs.com/functionendless/p/9556685.html
Copyright © 2011-2022 走看看