[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;
}
posted @ 2026-04-01 21:32  califeee  阅读(3)  评论(0)    收藏  举报