NOI 2025 见!

 

题解:CF2128D Sum of LDS

简要题意

给定一个长度为 \(n\) 的排列 \(p_1, p_2, \ldots, p_n\),并且对所有 \(1 \le i \le n-2\) 都满足 \(\max(p_i, p_{i+1}) > p_{i+2}\)

请计算:对所有满足 \(1 \le l \le r \le n\) 的子数组 \((p_l, p_{l+1}, \ldots, p_r)\),其最长严格下降子序列(LDS)的长度之和。

思路

\(p_{n+1} = p_{n+2} = p_{n+3} = -\infty\)\(\{i_1, \ldots, i_m\}\) 为所有满足 \(p_i > p_{i+1}\)\(i \in [n]\) 组成的集合。

可以分两步证明,序列 \((i_1, \ldots, i_m)\)\(p\) 的一个 LDS。

它是单调递减的

\(k \in [m]\)

情况 1:\((i_k) + 1 = i_{k+1}\)

按照集合构造规则,直接有 \(p_{i_k} > p_{(i_k) + 1} = p_{i_{k+1}}\)

情况 2:\((i_k) + 1 < i_{k+1}\)

此时,根据题意,有 \(\max(p_{i_k}, p_{(i_k) + 1}) > p_{(i_k) + 2}\)

\((i_k) + 1 < i_{k+1}\),说明 \((i_k) + 1\) 没有被选入集合,又说明 \(p_{(i_k) + 1} < p_{(i_k) + 2}\),所以 \(p_{i_k} > p_{(i_k) + 2}\) 只能成立,否则 \(\max(p_{i_k}, p_{(i_k) + 1}) > p_{(i_k) + 2}\) 不成立。

别忘了,根据规则,现在不仅有 \(p_{i_k} > p_{(i_k) + 2}\),还有 \(p_{i_k} > p_{(i_k) + 1}\)。根据题意,又有 \(p_{i_k} > \max(p_{(i_k) + 1}, p_{(i_k) + 2}) > p_{(i_k) + 3)}\),于是就有了传递性,可以一路传出去了。

综上所述,\(p_{i_k} > \max(p_{(i_k) + 1}, p_{(i_k) + 2}, \ldots, p_{n})\) 恒成立,单调性得证。

它是最长的

注意到,若 \(p_i < p_{i + 1}\),那么 \(i\)\(i + 1\) 至多只能选择其中一个存在于 LDS 中。

因此答案的上界为 \(n - \sum_{i=1}^{n-1} \left[p_i < p_{i+1}\right]\),即 \(n - (n - m) = m\),注意到 \(|\{i_1, \ldots, i_m\}| = m\),正好达到上界,最优性得证。


综上所述,\((i_1, \ldots, i_m)\)\(p\) 的一个 LDS。

因此原问题被转换成了:计算 \(\sum_{l=1}^{n} \sum_{r=l}^n 1 + \sum_{k=l}^{r-1} [p_k > p_{k+1}]\) 的值。

相信有良好普及组基础的同学,可以轻松地在 \(\Theta(n)\) 的时空复杂度下解决此问题。

实现

#include <bits/stdc++.h>
using namespace std;

using ll = long long;

constexpr int N = 500000 + 1;

int a[N];

void solve() {
	int n;
	cin >> n;
	for (int i = 1; i <= n; ++i) {
		cin >> a[i];
	}
	ll ans = 0;
	for (int i = 1; i < n; ++i) if (a[i] > a[i + 1]) {
		ans += (ll)i * (n - i);
	}
	cout << ans + ((ll)n * (n + 1) >> 1) << '\n';
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int t;
	cin >> t;
	while (t--) {
		solve();
	}
	return 0;
}

时空复杂度:均为 \(\Theta(n)\)

posted on 2025-08-12 21:37  SkyWave2022  阅读(35)  评论(0)    收藏  举报

导航