Автор задачі: | Hadi Takla (TaklaOI) |
Підготував: | Hadi Takla (TaklaOI) |
Відредагував: | Hadi Takla (TaklaOI) |
Розв'язок
По-перше, будь-яка пара зі значенням або є fe3b0onacci-парою.
оскільки \text{Fib}(x + 0) = \text{Fib}(x) = \text{Fib}(x) + 0 = \text{Fib}(x) + \text{Fib}(0) і навпаки.
тепер скористаємося формулою числа Фібоначчі
отже \text{Fib}(a_i + a_j) = \text{Fib}(a_i + a_j - 1) + \text{Fib}(a_i + a_j -2).
але нам потрібно \text{Fib}(a_i + a_j) = \text{Fib}(a_i) + \text{Fib}(a_j).
порівнюючи дві формули, отримаємо такі два рівняння.
додавши два рівняння.
після спрощення
підставляючи значення для a_i, можна знайти a_j.
при a_i = 0, a_j = 3, що має вигляд .
при a_i = 1, a_j = 2, тому пара зі значенням є fe3b0onacci-парою.
при a_i = 2, a_j = 1, тому пара зі значенням є fe3bo0nacci-парою.
при a_i = 3, a_j = 0, що має вигляд .
але є особливий випадок, коли a_i + a_j = 4
\text{Fib}(4) = \text{Fib}(3) + \text{Fib}(2).
але оскільки \text{Fib}(2) = \text{fib(1)} = 1, можна переписати таким чином.
\text{Fib}(4) = \text{Fib}(3) + \text{Fib}(1) або навпаки.
тому пара зі значенням або є fe3b0onacci-парою.
отже, остаточна відповідь дорівнює \frac{cnt_0 \cdot (cnt_0 - 1)}{2} + cnt_0 \cdot (n - cnt_0) + cnt_1 \cdot cnt_2 + cnt_1 \cdot cnt_3.
де cnt_i — це частота значення в масиві.
Часова складність: .
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
#define F first
#define S second
using namespace std;
const int N = 2e5 + 1;
const int M = 1e9 + 7;
signed main()
{
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int tc = 1;
cin>>tc;
while(tc--)
{
int n;
cin>>n;
int a[n+1];
int ans = 0 , cnt0 = 0 ,cnt1 = 0 , cnt2 = 0 , cnt3 = 0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
cnt0 += (a[i] == 0);
cnt1 += (a[i] == 1);
cnt2 += (a[i] == 2);
cnt3 += (a[i] == 3);
}
ans += cnt0 * (cnt0 - 1)/2; // 0 0
ans += cnt0 * (n - cnt0); // (0,x) , (x,0)
ans += cnt1 * cnt2; // (1,2) , (2,1)
ans += cnt1 * cnt3; // (1,3) , (3,1)
cout<<ans<<endl;
}
}