zoukankan      html  css  js  c++  java
  • [SOJ #47]集合并卷积

    题目大意:给你两个多项式$A,B$,求多项式$C$使得:
    $$
    C_n=sumlimits_{x|y=n}A_xB_y
    $$
    题解:$FWT$,他可以解决形如$C_n=sumlimits_{xoplus y=n}A_xB_y$的问题,其中$oplus$为位运算(一般为$or,and,xor$)

    or:

    void FWT(int *A) {
    	for (int mid = 1; mid < lim; mid <<= 1)
    		for (int i = 0; i < lim; i += mid << 1)
    			for (int j = 0; j < mid; ++j) A[i + j + mid] += A[i + j];
    }
    void IFWT(int *A) {
    	for (int mid = 1; mid < lim; mid <<= 1)
    		for (int i = 0; i < lim; i += mid << 1)
    			for (int j = 0; j < mid; ++j) A[i + j + mid] -= A[i + j];
    }
    

      

    and:

    void FWT(int *A) {
    	for (int mid = 1; mid < lim; mid <<= 1)
    		for (int i = 0; i < lim; i += mid << 1)
    			for (int j = 0; j < mid; ++j) {
    				int X = A[i + j], Y = A[i + j + mid];
    				A[i + j] = X + Y, A[i + j + mid] = X - Y;
    			}
    }
    void IFWT(int *A) {
    	for (int mid = 1; mid < lim; mid <<= 1)
    		for (int i = 0; i < lim; i += mid << 1)
    			for (int j = 0; j < mid; ++j) {
    				int X = A[i + j], Y = A[i + j + mid];
    				A[i + j] = X + Y, A[i + j + mid] = X - Y;
    			}
    	for (int i = 0; i < lim; ++i) A[i] /= lim;
    }
    

      

    xor:

    void FWT(int *A) {
    	for (int mid = 1; mid < lim; mid <<= 1)
    		for (int i = 0; i < lim; i += mid << 1)
    			for (int j = 0; j < mid; ++j) {
    				int X = A[i + j], Y = A[i + j + mid];
    				A[i + j] = X + Y, A[i + j + mid] = X - Y;
    			}
    }
    void IFWT(int *A) {
    	for (int mid = 1; mid < lim; mid <<= 1)
    		for (int i = 0; i < lim; i += mid << 1)
    			for (int j = 0; j < mid; ++j) {
    				int X = A[i + j], Y = A[i + j + mid];
    				A[i + j] = X + Y, A[i + j + mid] = X - Y;
    			}
    	for (int i = 0; i < lim; ++i) A[i] /= lim;
    }
    

      

    卡点:

    C++ Code:

    #include <cstdio>
    #include <cctype>
    inline int read() {
    	static int ch;
    	while (isspace(ch = getchar())) ;
    	return ch & 15;
    }
    
    #define N 1048576
    int lim;
    inline void init(const int n) {
    	lim = 1; while (lim < n) lim <<= 1;
    }
    inline void FWT(long long *A) {
    	for (int mid = 1; mid < lim; mid <<= 1) 
    		for (int i = 0; i < lim; i += mid << 1) 
    			for (int j = 0; j < mid; ++j) A[i + j + mid] += A[i + j];
    }
    inline void IFWT(long long *A) {
    	for (int mid = 1; mid < lim; mid <<= 1) 
    		for (int i = 0; i < lim; i += mid << 1) 
    			for (int j = 0; j < mid; ++j) A[i + j + mid] -= A[i + j];
    }
    
    int n;
    long long A[N], B[N];
    int main() {
    	scanf("%d", &n);
    	for (int i = 0; i < n; ++i) A[i] = read();
    	for (int i = 0; i < n; ++i) B[i] = read();
    	init(n);
    	FWT(A), FWT(B);
    	for (int i = 0; i < lim; ++i) A[i] *= B[i];
    	IFWT(A);
    	for (int i = 0; i < n; ++i) {
    		printf("%lld", A[i]);
    		putchar(i == (n - 1) ? '
    ' : ' ');
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    Swift和Objective-C混编注意
    【算法设计与数据结构】为何程序员喜欢将INF设置为0x3f3f3f3f?(转)
    baidu网盘下载神器 Pandownload
    为什么大学要学一堆纸上谈兵的课程?(转)
    数据结构实训——校园导游系统
    数据结构实训——哈希表设计
    数据结构实训——员工管理系统
    数据结构实训——成绩统计系统
    数据结构——链表实现一元多项式的表示和加法
    数据结构——顺序表的一些算法
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10259231.html
Copyright © 2011-2022 走看看