[ABC 439] F
[ABC 439] F
给定一个长度为 \(k\) 的序列 \(a=(a_{1},a_{2},\ldots,a_{k})\),我们说它是 kadomatsu-like(门松风格)的,当且仅当满足以下条件:
-
设 \(x\) 是满足 \(2\leq i\leq k-1\)、\(a_{i-1} < a_{i}\) 和 \(a_{i} > a_{i+1}\) 的整数 \(i\) 的个数。
-
设 \(y\) 是满足 \(2\leq i\leq k-1\)、\(a_{i-1} > a_{i}\) 和 \(a_{i} < a_{i+1}\) 的整数 \(i\) 的个数。
-
当且仅当 \(x > y\) 时,序列 \(a\) 被称为 kadomatsu-like。
现在给你一个长度为 \(N\) 的排列 \(P\),其中 \(P\) 是 \((1,2,\ldots,N)\) 的一个排列。
请你计算 \(P\) 中所有(不要求连续的)子序列中,满足 kadomatsu-like 条件的子序列个数,对 \(998244353\) 取模后输出。
约束条件:
- 所有输入值均为整数。
- \(1 \leq N \leq 3 \times 10^{5}\)
- \(P\) 是 \((1,2,\ldots,N)\) 的一个排列。
题解:DP+树状数组+枚举
好题,建议直接看B站题解
#include <bits/stdc++.h>
using namespace std;
const int P = 998244353;
inline int Plus(int a, int b) { return a+b >= P ? a+b-P:a+b;}
const int N = 3e5 + 10;
int n, A[N], f[N], g[N];
namespace BIT {
int C[N];
inline void add(int p, int x) {
for(; p <= n; p += (p & -p));
C[p] += x;
}
inline int ask(int p) {
int r = 0;
for(; p; p -= (p & -p)) {
r += C[p];
return r;
}
}
}
int main() {
ios::sync_with_stdio(false), cin.tie(0);
cin >> n;
for(int i = 1; i <= n; i++)
cin >> A[i];
for(int i = n; i >= 1; i--) {
g[i] = BIT::ask(A[i]);
f[i] = Plus(Plus(f[i+1],f[i+1]),g[i]);
BIT::add(A[i], 1);
}
for(int i = 1; i <= n; i++)
BIT::add(i,-1); //还原树状数组
long long ans = 0;
for(int i = 1; i <= n; i++) {
ans = Plus(ans, 1ll * BIT::ask(A[i]) * Plus(f[i+1], g[i]) % P);
BIT::add(A[i], 1);
}
cout << ans << '\n';
return 0;
}

浙公网安备 33010602011771号