Автор задачі: | Hadi Takla (TaklaOI) |
Підготував: | Hadi Takla (TaklaOI) |
Відредагував: | Hadi Takla (TaklaOI) |
Розв'язок
Факт: індекс у вихідному масиві може мати будь-який індекс (1\le j \le i) у підпослідовності.
Якщо ми хочемо, щоб індекс мав індекс у підпослідовності, ми повинні вибрати j-1 елемент із i-1 елементів перед , а з наступних n-i елементів можемо вибирати довільно.
Отже, кількість підпослідовностей, у яких індекс вихідного масиву є -м у підпослідовності, дорівнює:
Таким чином, ми можемо обчислити відповідь за формулою:
Але це розв'язок за \mathcal{O}(n^2), який не вкладається в обмеження.
Тому нехай con_i = \sum_{j=1}^{i} \binom{i-1}{j-1} \cdot (-a_i)^j.
Відповідь матиме вигляд:
.
Тепер запишемо con_i наступним чином:
Отже, ми можемо окремо виділити парні та непарні індекси.
Тому запишемо con_i = even_i - odd_i,
де even_i — сума за парними значеннями , а odd_i — сума за непарними значеннями .
Тепер спробуємо спростити even_i та odd_i.
Коли парне, j-1 непарне.
Тому якщо покладемо 2k + 1 = j-1 j = 2k + 2,
ми можемо записати even_i наступним чином:
що дорівнює
.
Тепер бачимо, що \sum_{k=0}^{\lfloor \frac{i-1}{2} \rfloor} \binom{i-1}{2k+1} \cdot a_i ^ {2k+1} — це сума елементів на парних позиціях у біноміальному розкладі, що дорівнює:
Отже, even_i дорівнює a_i \cdot \frac {(1 + a_i)^{i-1} - (1 - a_i)^{i-1}}{2}.
Тепер аналогічно для odd_i.
Коли непарне, j-1 парне.
Тому якщо покладемо 2k = j-1 j = 2k + 1,
ми можемо записати odd_i наступним чином:
що дорівнює
.
Бачимо, що \sum_{k=0}^{\lfloor \frac{i-1}{2} \rfloor} \binom{i-1}{2k} \cdot a_i ^ {2k} — це сума елементів на непарних позиціях у біноміальному розкладі, що дорівнює:
Отже, odd_i дорівнює a_i \cdot \frac {(1 + a_i)^{i-1} + (1 - a_i)^{i-1}}{2}.
Повертаючись до con_i = even_i - odd_i:
con_i = a_i \cdot \frac {(1 + a_i)^{i-1} - (1 - a_i)^{i-1}}{2} - a_i \cdot \frac {(1 + a_i)^{i-1} + (1 - a_i)^{i-1}}{2}.
= -a_i \cdot (1-a_i)^{i-1}.
ans = \sum_{i=1}^{n} 2^{n-1} \cdot con_i.
.
Часова складність: \mathcal{O}(n \text{log}(\text{max}(a_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;
int add(int a,int b)
{
a %= M;
b %= M;
return (a+b+M)%M;
}
int sub(int a,int b)
{
a %= M;
b %= M;
return (a-b+M)%M;
}
int mul(int a,int b)
{
a %= M;
b %= M;
int res = a*b;
res %= M;
res += M;
res %= M;
return res;
}
int pwr(int x,int y)
{
if(y == 0)
return 1;
int res = pwr(x,y/2);
res = mul(res,res);
if(y % 2)
res = mul(res , x);
return res;
}
int divi(int a,int b)
{
return mul(a , pwr(b,M-2));
}
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 ans = 0;
int a[n+1];
for(int i=1;i<=n;i++){
cin>>a[i];
int tmp = pwr(2 , n-i);
tmp = mul(tmp , a[i]);
tmp = mul(tmp , pwr(sub(1 , a[i]) , i-1));
tmp = mul(tmp , -1);
ans = add(ans , tmp);
}
cout<<ans<<endl;
}
}