题意:给定一个数组,求有多少个子序列满足最后一项大于等于第一项。
思路:首先我们知道如果a[j]>=a[i],并且j>i,那么贡献就是2的(j-i-1)次方。所以我们对于枚举每个i,用树状数组维护前面比他小的点权值为2的i次方的逆元。
/*keep on going and never give up*/
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
#define int long long
typedef pair<int, int> pii;
#define lowbit(x) x&(-x)
#define endl '\n'
#define wk is zqx ta die
const int mod = 998244353;
int aq[300005];
int f[300005];
int n;
int pow(int a, int b) {
int res = 1;
while (b) {
if (b & 1) {
res = res * a % mod;
}
a = a * a % mod;
b >>= 1;
}
return res;
}
void add(int x, int y) {
while (x <= n) {
f[x] = (f[x] + y) % mod;
x += lowbit(x);
}
}
int query(int x) {
int res = 0;
while (x) {
res = (f[x] + res) % mod;
x -= lowbit(x);
}
return res;
}
signed main() {
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
vector<int> pl;
auto get = [&](int x) {
return lower_bound(pl.begin(), pl.end(), x) - pl.begin() + 1;
};
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> aq[i];
pl.push_back(aq[i]);
}
sort(pl.begin(), pl.end());
pl.erase(unique(pl.begin(), pl.end()), pl.end());
int ans = 0;
for (int i = 1; i <= n; i++) {
int c = get(aq[i]);
int sum = query(c);
ans = (ans + pow(2, i - 1) * sum % mod) % mod;
int m = pow(2, i);
int k = pow(m, mod - 2) % mod;
add(c, k);
}
cout << ans << endl;
return 0;
}