Advertisement
Guest User

Untitled

a guest
Oct 1st, 2014
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.36 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <vector>
  4. #include <algorithm>
  5. #include <queue>
  6. #include <stack>
  7. #include <numeric>
  8. #include <cstdio>
  9. #include <cmath>
  10. #include <map>
  11. #include <climits>
  12. #include <set>
  13. #include <string>
  14. #include <sstream>
  15. #include <complex>
  16. #define FOR(i,a,b) for(__typeof(b) i=a; i<(b); ++i)
  17. #define FOR0(i,b) for(__typeof(b) i=0; i<(b); ++i)
  18. #define TRAV(it,c) for(__typeof((c).begin()) it=(c).begin(); it!=(c).end(); ++it)
  19. #define RTRAV(it,c) for(__typeof((c).rbegin()) it=(c).rbegin(); it!=(c).rend(); ++it)
  20. using namespace std;
  21. typedef pair<int, int> pii;
  22. typedef vector<int> vi;
  23. typedef vector<bool> vb;
  24. typedef vector<vb> vbb;
  25. typedef vector<vi> vii;
  26. typedef vector<pii> vpii;
  27. typedef long long ll;
  28. typedef long double ld;
  29.  
  30. #define MAX_SIZE 33000
  31.  
  32. ll quad_total_clocks=0;
  33. ll fft_total_clocks=0;
  34.  
  35. ll quad_total_mult=0;
  36. ll quad_total_sum=0;
  37.  
  38. ll fft_total_mult=0;
  39. ll fft_total_sum=0;
  40.  
  41. void multpoly_quad(int n, double A[], double B[], double C[]){
  42.     FOR0(i, 2*n-1){
  43.         C[i] = 0;
  44.         FOR(j, i-n+1, i+1){
  45.             C[i] += A[j]*B[i-j];
  46.         }
  47.     }
  48.     quad_total_mult += (2*n-1)*n;
  49.     quad_total_sum += (2*n-1)*n;;
  50. }
  51.  
  52. typedef complex<double> complex_t;
  53. typedef vector<complex_t> vc;
  54.  
  55. int round_to_pot2(int n){
  56.     return static_cast<int>( ( 1 << (static_cast<int>(ceil( log(n)/log(2) ))) ) );
  57. }
  58.  
  59. void fft(const vc& a, vc& y){
  60.     size_t n = a.size();
  61.    
  62.     if( n == 1 ){
  63.         y.assign(a.begin(), a.end());
  64.         return;
  65.     }
  66.    
  67.     vc a1, a0;
  68.     a1.reserve(n+10); a0.reserve(n+10);
  69.    
  70.     FOR0(i, n/2){
  71.         a1.push_back( a[ 2*i + 1 ] );
  72.         a0.push_back( a[ 2*i ] );
  73.     }
  74.    
  75.     vc y0,y1;
  76.     fft(a0,y0);
  77.     fft(a1,y1);
  78.  
  79.     complex_t wn(cos(2*M_PI/n), sin(2*M_PI/n));
  80.     complex_t w(1,0);
  81.    
  82.     y.clear(); y.resize(n);
  83.    
  84.     FOR0(k, n/2){
  85.         y[k] = y0[k] + w*y1[k];
  86.         y[k+n/2] = y0[k] - w*y1[k];
  87.         w *= wn;
  88.     }
  89.    
  90. }
  91.  
  92. void inv_fft(const vc& y, vc& a){
  93.     size_t n = y.size();
  94.    
  95.     if( n == 1 ){
  96.         a.assign(y.begin(), y.end());
  97.         return;
  98.     }
  99.    
  100.     vc y1, y0;
  101.     y1.reserve(n+10); y0.reserve(n+10);
  102.    
  103.     FOR0(i, n/2){
  104.         y1.push_back( y[ 2*i + 1 ] );
  105.         y0.push_back( y[ 2*i ] );
  106.     }
  107.    
  108.     vc a0, a1;
  109.     inv_fft(y0, a0);
  110.     inv_fft(y1, a1);
  111.    
  112.     complex_t wn(cos(-2*M_PI/n), sin(-2*M_PI/n));
  113.     complex_t w(1,0);
  114.    
  115.     a.clear(); a.resize(n);
  116.    
  117.     FOR0(k, n/2){
  118.         a[k] = a0[k] + w*a1[k];
  119.         a[k+n/2] = a0[k] - w*a1[k];
  120.         w *= wn;
  121.     }
  122.    
  123. }
  124.  
  125. void multpoly_fft(int n, double A[], double B[], double C[]){
  126.     int round_n = round_to_pot2(n)*2;
  127.  
  128.     vc a_complex, b_complex;
  129.     a_complex.reserve(round_n);
  130.     b_complex.reserve(round_n);
  131.  
  132.     FOR0(i, round_n){
  133.         a_complex.push_back( ( (i>=n) ? 0 : A[i] ) );
  134.         b_complex.push_back( ( (i>=n) ? 0 : B[i] ) );
  135.     }
  136.  
  137.     vc ft_a, ft_b;
  138.     fft(a_complex,ft_a);
  139.     fft(b_complex,ft_b);
  140.  
  141.     vc ft_c;
  142.     ft_c.reserve(round_n);
  143.     FOR0(i, round_n) ft_c.push_back( ft_a[i] * ft_b[i] );
  144.  
  145.     vc inv_ft_c;
  146.     inv_fft(ft_c, inv_ft_c);
  147.  
  148.     FOR0(i, 2*n-1) C[i] = inv_ft_c[i].real()/round_n;
  149.  
  150. }
  151.  
  152. int main(int argc, char **argv){
  153.     ios::sync_with_stdio(false);
  154.  
  155.     if( argc != 2 ){
  156.         cout << "Numero invalido de argumentos!\n";
  157.         return 1;
  158.     }
  159.  
  160.     fstream fin( argv[1] );
  161.     int pairs; fin >> pairs;
  162.  
  163.     FOR0(p, pairs){
  164.  
  165.         double A[MAX_SIZE], B[MAX_SIZE], C[MAX_SIZE];
  166.  
  167.         int n_a; fin >> n_a;
  168.         FOR0(i,n_a) fin >> A[i];
  169.  
  170.  
  171.         int n_b; fin >> n_b;
  172.         FOR0(i,n_b) fin >> B[i];
  173.  
  174.         multpoly_quad(max(n_a, n_b),A,B,C);
  175.         multpoly_fft(max(n_a, n_b),A,B,C);
  176.     }
  177.  
  178.     return 0;
  179. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement