8372. Triple sumsproblem code: tsum |
You're given a sequenceSOfNDistinct integers.
Consider all the possible sums of three integers from the sequence at three different indicies.
For each obtainable sum output the number of different triples of indicies that generate it.
Constraints:
N <= 40000, | Si | <= 20000
Input
The first line of input contains a single integer n.
Each of the next n lines contain an element of S.
Output
Print the solution for each possible sum in the following format:
Sum_value: number_of_triples
Smaller sum values shocould be printed first.
Example
Input:
5
-1
2
3
0
5
Output:
1 : 1
2 : 1
4 : 2
5 : 1
6 : 1
7 : 2
8 : 1
10 : 1
Explanation:
4 can be obtained using triples (0, 1, 2) and (0, 3, 4 ).
7 can be obtained using triples (0, 2, 4) and (1, 3, 4 ).
Note:A triple is considered the same as any of its permutations.
A Polynomial \ (P \) indicating the number of occurrences of the bit index in S is used to represent an upper index, then, the three-way representation is \ (P ^ 3 \). Then, due to the difference in the ordinal number of the elements of the three tuples in S, the review principle can be used to determine the weight.
#include <bits/stdc++.h>using namespace std;typedef complex<long double> Complex;const int maxn = 1 << 17;const int base = 20000;void DFT(Complex *a, int N, int flag) { for(int i = (N >> 1), j = 1, k; j < N; i ^= k, ++j) { if(i < j) swap(a[i], a[j]); for(k = (N >> 1); i & k; i ^= k, k >>= 1); } for(int n = 2; n <= N; n <<= 1) { Complex Wn = Complex(cos(flag * M_PI * 2 / n), sin(flag * M_PI * 2 / n)); for(int i = 0; i < N; i += n) { Complex W = Complex(1.0, 0.0); for(int j = i; j < i + (n >> 1); W = W * Wn, ++j) { Complex u = a[j], v = W * a[j + (n >> 1)]; a[j] = u + v; a[j + (n >> 1)] = u - v; } } }}int a[maxn], b[maxn], c[maxn];Complex A[maxn], B[maxn], C[maxn];int main() { int n; scanf("%d", &n); for(int i = 1, x; i <= n; ++i) { scanf("%d", &x); x += base; ++a[x]; ++b[x + x]; ++c[x + x + x]; } int N = maxn; for(int i = 0; i < N; ++i) { A[i] = a[i], B[i] = b[i]; } DFT(A, N, 1); DFT(B, N, 1); for(int i = 0; i < N; ++i) { C[i] = A[i] * (A[i] * A[i] - 3.0l * B[i]); } DFT(C, N, -1); for(int i = 0; i < N; ++i) { long long ans = ((long long)(C[i].real() / N + 0.5) + 2 * c[i]) / 6; if(ans != 0) { printf("%d : %lld\n", i - 60000, ans); } } return 0;}
Spoj 8372. Triple sums