G - Fine Triplets / Time Limit: 3 sec / Memory Lim...
Создано: 8 февраля 2025 г.
Создано: 8 февраля 2025 г.
G - Fine Triplets /
Time Limit: 3 sec / Memory Limit: 1024 MB
×
It is prohibited to use generative AI in ongoing AtCoder contests. Please refer to the following rules for more details.
AtCoder Rules against Generative AI - Version 20241206
Score :
600 points
Problem Statement
For integers
A,B,C (
A<B<C ), if they satisfy
B−A=C−B, then
(A,B,C) is called a fine triplet.
You are given a set of
N distinct positive integers
S={S
1
,S
2
,…,S
N
}. Find the number of fine triplets
(A,B,C) with
A,B,C∈S.
Constraints
All input values are integers.
1≤N≤10
6
1≤S
i
≤10
6
The elements of
S are distinct.
Input
The input is given from Standard Input in the following format:
N
S
1
S
2
…
S
N
Output
Print the number of fine triplets as an integer.
Sample Input 1
Copy
5
8 3 1 5 2
Sample Output 1
Copy
3
Here,
S={8,3,1,5,2}. The fine triplets to be counted are the following three:
(1,2,3)
(1,3,5)
(2,5,8)
Sample Input 2
Copy
7
300000 100000 499998 499999 200000 400000 500000
Sample Output 2
Copy
5
Sample Input 3
Copy
10
13 1 16 15 12 4 7 10 2 19
Sample Output 3
Copy
10
Language
Source Code
at most 512 KiB
Your source code will be saved as Main.extension.
Please give correct c++ code all tests pass please and also give FULL all test pass code please and look constraints and using constratints give optimzed code but all tests pass code please take care of this...!!
all tests paas please
We can solve this problem by “counting” each valid arithmetic progression in . Recall that a triple (with ) is a fine triplet if and only if
One neat idea is to “fix” the middle element (which must lie in ) and then count how many pairs (with ) satisfy
Notice that if is a solution (with ) then automatically one of or is less than and the other is greater than (since if both were on one side the sum would be either too small or too large).
A standard observation is that if we define an indicator function
then for any integer the convolution
counts the number of pairs with and .
Now, note that when we have:
Thus, if then
In other words, the number of valid pairs (which give a fine triplet with middle ) is
Thus the final answer is:
The challenge is to compute the convolution quickly. Since all are positive integers and , we can define an array of length (say) where
Then the convolution can be computed via Fast Fourier Transform (FFT) in time. (The resulting convolution will have length up to roughly .)
The code below implements the FFT (using the standard iterative method) and then computes the convolution. Finally, for each we add
to the answer. (We use llround
to convert from the floating‐point result of the FFT back to an integer.)
Below is the full optimized C++ code:
cpp#include <bits/stdc++.h> using namespace std; typedef complex<double> cd; // Iterative FFT implementation. void fft(vector<cd> & a, bool invert) { int n = a.size(); for (int i = 1, j = 0; i < n; i++) { int bit = n >> 1; for(; j & bit; bit >>= 1) j -= bit; j += bit; if(i < j) swap(a[i], a[j]); } for (int len = 2; len <= n; len <<= 1) { double ang = 2 * M_PI / len * (invert ? -1 : 1); cd wlen(cos(ang), sin(ang)); for (int i = 0; i < n; i += len) { cd w(1); for (int j = 0; j < len/2; j++) { cd u = a[i+j], v = a[i+j+len/2] * w; a[i+j] = u + v; a[i+j+len/2] = u - v; w *= wlen; } } } if(invert) { for (int i = 0; i < n; i++) a[i] /= n; } } int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int N; cin >> N; vector<int> S(N); int maxVal = 0; for (int i = 0; i < N; i++){ cin >> S[i]; if(S[i] > maxVal) maxVal = S[i]; } // Our f(x) array will be of size m = maxVal + 1. int m = maxVal + 1; // Build the indicator function f. vector<cd> poly(m, 0); for (int x : S) { poly[x] = 1; } // We need to compute the convolution f*f. // The required size is at least (2*m - 1). int n = 1; while(n < 2 * m - 1) n <<= 1; poly.resize(n); // Perform FFT on poly. fft(poly, false); for (int i = 0; i < n; i++){ poly[i] *= poly[i]; } fft(poly, true); // Now poly[k] (rounded) is equal to (f*f)(k). // For each B in S, the number of fine triplets with B as the middle is ((poly[2*B] - 1) / 2). long long ans = 0; for (int b : S) { int idx = 2 * b; if(idx < (int)poly.size()){ long long convVal = (long long)llround(poly[idx].real()); // Subtract the self-pair (b,b) convVal -= 1; convVal /= 2; if(convVal > 0) ans += convVal; } } cout << ans << "\n"; return 0; }
Input Reading and Setup:
maxVal
) and set the size .poly
(of type vector<cd>
) such that poly[x] = 1
if and 0 otherwise.FFT Setup:
n
, the next power of 2 at least .poly
, square each value (this corresponds to convolution in the frequency domain) and then perform the inverse FFT to obtain the convolution .Counting the Fine Triplets:
This code is optimized to run under the given constraints and should pass all test cases.
Happy coding!