Advertisement
RaFiN_

Triple sum

Sep 27th, 2019
277
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.85 KB | None | 0 0
  1. /* You're given a sequence s of N distinct integers.
  2. Consider all the possible sums of three integers from the sequence at three different indicies.
  3. For each obtainable sum output the number of different triples of indicies that generate it.
  4. SPOJ triple sum
  5. solution : The general meaning of the question: give you N numbers, and then pick any three numbers and sum them, let you output the sum of the possible and corresponding to the number of programs.
  6.         Since it is addition, consider using the generator function, multiplying two generator functions to get the sum of any two items, and the three are the same. Since |si| <=20000, the si is first enlarged by 20,000 to prevent negative numbers. Let A be the corresponding generator function, we can find that the result of A*A*A is repeated. A*A*A=three numbers are the same + two of them are the same + three numbers are not the same. So consider the tolerance, minus the repetition. Let A*A*A denote the whole, B denote two identical numbers, then A*B=two of them are the same + three numbers are different. Consider again the coefficients of the repulsion, where the two numbers are the same, the two numbers can be combined in three positions, C(3,2)=3. So the answer is to subtract 3*A*B. The current answer is A*A*A-3*A*B. We found that the three numbers were not calculated the same twice, so I made up for it. With C, I took three identical numbers, and the answer became A*A*A-3*A*B+2*C. It is now guaranteed that the three numbers are not the same, but the combination of three different numbers has 3!, so the final answer is divided by 6. See the code for details.
  7. */
  8.   typedef complex < double > base ;
  9.   const double PI = 2*acos( 0.0 );
  10.  
  11. void fft ( vector < base > & a, bool invert ) {
  12.     int n = ( int ) a. size ( ) ;
  13.  
  14.     for ( int i = 1 , j = 0 ; i < n ; ++ i ) {
  15.         int bit = n >> 1 ;
  16.         for ( ; j >= bit ; bit >>= 1 )
  17.             j -= bit ;
  18.         j += bit ;
  19.         if ( i < j )
  20.             swap ( a [ i ] , a [ j ] ) ;
  21.     }
  22.  
  23.     for ( int len = 2 ; len <= n ; len <<= 1 ) {
  24.         double ang = 2 * PI / len * ( invert ? - 1 : 1 ) ;
  25.         base wlen ( cos ( ang ) , sin ( ang ) ) ;
  26.         for ( int i = 0 ; i < n ; i += len ) {
  27.             base w ( 1 ) ;
  28.             for ( int j = 0 ; j < len / 2 ; ++ j ) {
  29.                 base u = a [ i + j ] ,  v = a [ i + j + len / 2 ] * w ;
  30.                 a [ i + j ] = u + v ;
  31.                 a [ i + j + len / 2 ] = u - v ;
  32.                 w *= wlen ;
  33.             }
  34.         }
  35.     }
  36.     if ( invert )
  37.         for ( int i = 0 ; i < n ; ++ i )
  38.             a [ i ] /= n ;
  39. }
  40.  
  41. void multiply ( const vector < ll > & a, const vector < ll > & b, vector < ll > & res ) {
  42.     vector < base > fa ( a. begin ( ) , a. end ( ) ) ,  fb ( b. begin ( ) , b. end ( ) ) ;
  43.     size_t n = 1 ;
  44.     while ( n < max ( a. size ( ) , b. size ( ) ) )  n <<= 1 ;
  45.     n <<= 1 ;
  46.     fa. resize ( n ) ,  fb. resize ( n ) ;
  47.  
  48.     fft ( fa, false ) ,  fft ( fb, false ) ;
  49.     for ( size_t i = 0 ; i < n ; ++ i )
  50.         fa [ i ] *= fb [ i ] ;
  51.     fft ( fa, true ) ;
  52.  
  53.     res. resize ( n ) ;
  54.     for ( size_t i = 0 ; i < n ; ++ i )
  55.         res [ i ] = (ll)( fa [ i ] . real ( ) + 0.5 ) ;
  56.     while(res.size()>1&&res.back()==0)res.pop_back();
  57.     /*  int carry = 0 ;
  58.     for ( size_t i = 0 ; i < n ; ++ i ) {
  59.         res [ i ] += carry ;
  60.         carry = res [ i ] / 10 ;
  61.         res [ i ] %= 10 ;
  62.     }*/
  63. }
  64.  
  65.  
  66.  
  67. int main(){
  68.    // booster();
  69.     //read("input.txt");
  70.  
  71.         vi a(81000,0);vi b(81000,0);vi c(150000,0);
  72.         vi res,res2;
  73.         int n,k;
  74.         int mx = 0;
  75.         scani(n);
  76.         for(int i = 0;i<n;i++){
  77.             int x;
  78.             scani(x);
  79.             a[x+MAX]++;
  80.             b[x+x+MAX+MAX]++;
  81.             c[x+x+x+MAX+MAX+MAX]++;
  82.         }
  83.        
  84.         multiply(a,a,res);
  85.         multiply(res,a,res);
  86.         multiply(a,b,res2);
  87.         for(int i = 0;i<res.size();i++){
  88.             res[i] = (res[i] - 3*res2[i] + 2*c[i])/6;
  89.         }
  90.         for(int i = 0;i<res.size();i++)if(res[i]>EPS)printf("%d : %d\n",i - 3*(MAX) ,res[i]);
  91.    
  92.  
  93.  
  94.     return 0;
  95. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement