Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <fstream>
- #include <vector>
- #include <algorithm>
- #include <queue>
- #include <stack>
- #include <numeric>
- #include <cstdio>
- #include <cmath>
- #include <map>
- #include <climits>
- #include <set>
- #include <string>
- #include <sstream>
- #include <complex>
- #define FOR(i,a,b) for(__typeof(b) i=a; i<(b); ++i)
- #define FOR0(i,b) for(__typeof(b) i=0; i<(b); ++i)
- #define TRAV(it,c) for(__typeof((c).begin()) it=(c).begin(); it!=(c).end(); ++it)
- #define RTRAV(it,c) for(__typeof((c).rbegin()) it=(c).rbegin(); it!=(c).rend(); ++it)
- using namespace std;
- typedef pair<int, int> pii;
- typedef vector<int> vi;
- typedef vector<bool> vb;
- typedef vector<vb> vbb;
- typedef vector<vi> vii;
- typedef vector<pii> vpii;
- typedef long long ll;
- typedef long double ld;
- #define MAX_SIZE 33000
- ll quad_total_clocks=0;
- ll fft_total_clocks=0;
- ll quad_total_mult=0;
- ll quad_total_sum=0;
- ll fft_total_mult=0;
- ll fft_total_sum=0;
- void multpoly_quad(int n, double A[], double B[], double C[]){
- FOR0(i, 2*n-1){
- C[i] = 0;
- FOR(j, i-n+1, i+1){
- C[i] += A[j]*B[i-j];
- }
- }
- quad_total_mult += (2*n-1)*n;
- quad_total_sum += (2*n-1)*n;;
- }
- typedef complex<double> complex_t;
- typedef vector<complex_t> vc;
- int round_to_pot2(int n){
- return static_cast<int>( ( 1 << (static_cast<int>(ceil( log(n)/log(2) ))) ) );
- }
- void fft(const vc& a, vc& y){
- size_t n = a.size();
- if( n == 1 ){
- y.assign(a.begin(), a.end());
- return;
- }
- vc a1, a0;
- a1.reserve(n+10); a0.reserve(n+10);
- FOR0(i, n/2){
- a1.push_back( a[ 2*i + 1 ] );
- a0.push_back( a[ 2*i ] );
- }
- vc y0,y1;
- fft(a0,y0);
- fft(a1,y1);
- complex_t wn(cos(2*M_PI/n), sin(2*M_PI/n));
- complex_t w(1,0);
- y.clear(); y.resize(n);
- FOR0(k, n/2){
- y[k] = y0[k] + w*y1[k];
- y[k+n/2] = y0[k] - w*y1[k];
- w *= wn;
- }
- }
- void inv_fft(const vc& y, vc& a){
- size_t n = y.size();
- if( n == 1 ){
- a.assign(y.begin(), y.end());
- return;
- }
- vc y1, y0;
- y1.reserve(n+10); y0.reserve(n+10);
- FOR0(i, n/2){
- y1.push_back( y[ 2*i + 1 ] );
- y0.push_back( y[ 2*i ] );
- }
- vc a0, a1;
- inv_fft(y0, a0);
- inv_fft(y1, a1);
- complex_t wn(cos(-2*M_PI/n), sin(-2*M_PI/n));
- complex_t w(1,0);
- a.clear(); a.resize(n);
- FOR0(k, n/2){
- a[k] = a0[k] + w*a1[k];
- a[k+n/2] = a0[k] - w*a1[k];
- w *= wn;
- }
- }
- void multpoly_fft(int n, double A[], double B[], double C[]){
- int round_n = round_to_pot2(n)*2;
- vc a_complex, b_complex;
- a_complex.reserve(round_n);
- b_complex.reserve(round_n);
- FOR0(i, round_n){
- a_complex.push_back( ( (i>=n) ? 0 : A[i] ) );
- b_complex.push_back( ( (i>=n) ? 0 : B[i] ) );
- }
- vc ft_a, ft_b;
- fft(a_complex,ft_a);
- fft(b_complex,ft_b);
- vc ft_c;
- ft_c.reserve(round_n);
- FOR0(i, round_n) ft_c.push_back( ft_a[i] * ft_b[i] );
- vc inv_ft_c;
- inv_fft(ft_c, inv_ft_c);
- FOR0(i, 2*n-1) C[i] = inv_ft_c[i].real()/round_n;
- }
- int main(int argc, char **argv){
- ios::sync_with_stdio(false);
- if( argc != 2 ){
- cout << "Numero invalido de argumentos!\n";
- return 1;
- }
- fstream fin( argv[1] );
- int pairs; fin >> pairs;
- FOR0(p, pairs){
- double A[MAX_SIZE], B[MAX_SIZE], C[MAX_SIZE];
- int n_a; fin >> n_a;
- FOR0(i,n_a) fin >> A[i];
- int n_b; fin >> n_b;
- FOR0(i,n_b) fin >> B[i];
- multpoly_quad(max(n_a, n_b),A,B,C);
- multpoly_fft(max(n_a, n_b),A,B,C);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement