Code Library Of Others/sgtlaugh/FFT Extended + OP.cpp
void build(int& a, long long* A, int& b, long long* B){
        while (a > 1 && A[a - 1] == 0) a--;
        while (b > 1 && B[b - 1] == 0) b--;

	    len = 1 << (32 - __builtin_clz(a + b) - (__builtin_popcount(a + b) == 1));
        for (int i = a; i < len; i++) A[i] = 0;
        for (int i = b; i < len; i++) B[i] = 0;

		if (!step++){
            dp[1] = inv[1] = complx(1);
            for (int i = 1; (1 << i) < MAXN; i++){
                double theta = (2.0 * acos(0.0)) / (1 << i);
                complx mul = complx(cos(theta), sin(theta));
                complx inv_mul = complx(cos(-theta), sin(-theta));

                int lim = 1 << i;
                for (int j = lim >> 1; j < lim; j++){
                    dp[2 * j] = dp[j], inv[2 * j] = inv[j];
                    inv[2 * j + 1] = inv[j] * inv_mul;
                    dp[2 * j + 1] = dp[j] * mul;
                }
            }
        }

        if (last != len){
            last = len;
            int bit = (32 - __builtin_clz(len) - (__builtin_popcount(len) == 1));
            for (int i = 0; i < len; i++) rev[i] = (rev[i >> 1] >> 1) + ((i & 1) << (bit - 1));
        }
	}
/// Pre-process roots, inverse roots and fft leaf index
Pre-process roots, inverse roots and fft leaf index
Pre - process roots inverse roots and fft leaf index
void build(int& a, long long* A, int& b, long long* B){
        while (a > 1 && A[a - 1] == 0) a--;
        while (b > 1 && B[b - 1] == 0) b--;
	    len = 1 << (32 - __builtin_clz(a + b) - (__builtin_popcount(a + b) == 1));
        for (int i = a; i < len; i++) A[i] = 0;
        for (int i = b; i < len; i++) B[i] = 0;
		if (!step++){
            dp[1] = inv[1] = complx(1);
            for (int i = 1; (1 << i) < MAXN; i++){
                double theta = (2.0 * acos(0.0)) / (1 << i);
                complx mul = complx(cos(theta), sin(theta));
                complx inv_mul = complx(cos(-theta), sin(-theta));
                int lim = 1 << i;
                for (int j = lim >> 1; j < lim; j++){
                    dp[2 * j] = dp[j], inv[2 * j] = inv[j];
                    inv[2 * j + 1] = inv[j] * inv_mul;
                    dp[2 * j + 1] = dp[j] * mul;
                }
            }
        }
        if (last != len){
            last = len;
            int bit = (32 - __builtin_clz(len) - (__builtin_popcount(len) == 1));
            for (int i = 0; i < len; i++) rev[i] = (rev[i >> 1] >> 1) + ((i & 1) << (bit - 1));
        }
	}
void build ( int & a , long long * A , int & b , long long * B ) { while ( a > 1 && A [ a - 1 ] == 0 ) a -- ; while ( b > 1 && B [ b - 1 ] == 0 ) b -- ; len = 1 << ( 32 - __builtin_clz ( a + b ) - ( __builtin_popcount ( a + b ) == 1 ) ) ; for ( int i = a ; i < len ; i ++ ) A [ i ] = 0 ; for ( int i = b ; i < len ; i ++ ) B [ i ] = 0 ; if ( ! step ++ ) { dp [ 1 ] = inv [ 1 ] = complx ( 1 ) ; for ( int i = 1 ; ( 1 << i ) < MAXN ; i ++ ) { double theta = ( 2.0 * acos ( 0.0 ) ) / ( 1 << i ) ; complx mul = complx ( cos ( theta ) , sin ( theta ) ) ; complx inv_mul = complx ( cos ( - theta ) , sin ( - theta ) ) ; int lim = 1 << i ; for ( int j = lim >> 1 ; j < lim ; j ++ ) { dp [ 2 * j ] = dp [ j ] , inv [ 2 * j ] = inv [ j ] ; inv [ 2 * j + 1 ] = inv [ j ] * inv_mul ; dp [ 2 * j + 1 ] = dp [ j ] * mul ; } } } if ( last != len ) { last = len ; int bit = ( 32 - __builtin_clz ( len ) - ( __builtin_popcount ( len ) == 1 ) ) ; for ( int i = 0 ; i < len ; i ++ ) rev [ i ] = ( rev [ i >> 1 ] >> 1 ) + ( ( i & 1 ) << ( bit - 1 ) ) ; } }
Pre-process roots, inverse roots and fft leaf index
Pre - process roots inverse roots and fft leaf index