题意
给你一个长度为n的数组a,问:有多少个子序列b(不一定连续)满足条件
假设
a
=
(
a
1
,
a
2
,
…
,
a
n
)
a = (a_1,a_2,\dots,a_n)
a=(a1,a2,…,an)
b
=
b
1
,
b
2
,
…
,
b
k
,
b
1
≤
b
k
b = {b_1, b_2,\dots,b_k}, \quad b_1 \le b_k
b=b1,b2,…,bk,b1≤bk
思路
先对数组进行离散化。对于子序列
(
a
i
,
…
,
a
j
)
(a_i,\dots,a_j)
(ai,…,aj),一种有
2
j
−
i
−
1
2^{j - i - 1}
2j−i−1种,以
a
j
a_j
aj结尾的子序列的数量等于
∑
i
=
1
j
−
1
2
j
−
i
−
1
=
2
j
−
1
∑
i
=
1
j
−
1
1
2
i
,
其
中
i
满
足
a
i
≤
a
j
\sum_{i = 1}^{j - 1}2^{j - i - 1} = 2^{j - 1} \sum _{i = 1}^{j - 1}{1 \over 2^i},其中~i~满足~a_i \le a_j
i=1∑j−12j−i−1=2j−1i=1∑j−12i1,其中 i 满足 ai≤aj对于如何计算
∑
i
=
1
j
−
1
1
2
i
\sum_{i = 1}^{j - 1}{1 \over 2^i}
∑i=1j−12i1,可以用树状数组存储
2
i
~{ 2^i}~
2i 的乘法逆元,利用ask()函数求和即可.最后:
a
n
s
=
∑
j
=
1
n
∑
i
=
1
j
−
1
2
j
−
i
−
1
ans = \sum_{j = 1}^n \sum_{i = 1}^{j - 1}2^{j - i - 1}
ans=j=1∑ni=1∑j−12j−i−1
#include<cstdio>
#include<deque>
#include<queue>
#include<set>
#include<cstdlib>
#include<string.h>
#include<string>
#include<iostream>
#include<cmath>
#include<unordered_map>
#include<map>
#include<algorithm>
#define endl "\n"
#define IOS ios::sync_with_stdio(0), cin.tie(0),cout.tie(0)
#define ft first
#define sd second
#define pll pair<ll, ll>
#define pii pair<int, int>
#define ll long long int
#define ull unsigned long long int
#define mt(a,b) memset(a, b, sizeof a)
//#define int long long
const double PI = acos(-1.0);
const int inf = 0x3f3f3f3f;
const int INF = 0x7fffffff;
using namespace std;
const int N = 4e5 + 7, M = 1e6 + 7;
int n;
ll mod = 998244353;
ll c[N];
int a[N], b[N];
ll ans[N];
ll ask(ll x)
{
ll ans = 0;
for (; x; x -= x & -x) ans = (ans + c[x]) % mod;
return ans;
}
void add(int x, ll y)
{
for (; x <= n; x += x & -x) c[x] += y;
}
ll power(ll a, ll b)
{
ll ans = 1;
for (; b; b >>= 1)
{
if (b & 1) ans = ans * a % mod;
a = a * a % mod;
}
return ans;
}
int main()
{
IOS;
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i], b[i] = a[i];
sort(b + 1, b + n + 1);
int idx = unique(b + 1, b + n + 1) - b;
for (int i = 1; i <= n; i++)
a[i] = lower_bound(b + 1, b + idx, a[i]) - b;
for (int i = 1; i <= n; i++)
{
ans[i] = ask(a[i]) * power(2, i - 1ll) % mod;
add(a[i], power(power(2, i), mod - 2));//乘法逆元
}
ll sum = 0;
for (int i = 1; i <= n; i++)
sum = (sum + ans[i]) % mod;
cout << sum << endl;
return 0;
}