Decinc Dividing

对于一个序列 \(A\),若其可以被拆分成可空子序列 \(B\) 和可空子序列 \(C\),使得:

  • 序列 \(B\) 单调递增

  • 序列 \(C\) 单调递减

则我们称序列 \(A\) 是好的。

给定长度为 \(n\) 的排列 \(P\),求 \(P\) 中好的子段数量。

\(1 \leq n \leq 2 \times 10^5\),\(1 \leq p_i \leq n\)。


先考虑对于单个序列 \(A\) 如何判断合法性。由于题目限制,\(A\) 中的元素两两不同。

考虑从前往后贪心地分配,不妨设 \(a_i\) 被划进递增子序列,则此时的递减子序列结尾应当越大越好。故我们设 \(f_i\) 表示在前 \(i\) 个数中,将 \(a_i\) 划进递增子序列时,递减子序列末尾的最大值。同理设 \(g_i\) 表示在前 \(i\) 个数中,将 \(a_i\) 划进递减子序列时,递增子序列末尾的最小值。

转移是容易的,我们可以做到 \(O(n)\) 判断一个子段是否合法,总时间复杂度为 \(O(n^3)\)。


注意到对于排列 \(P\) 的子段 \([l,r]\) 和 \([l',r']\),其中 \([l',r'] \subseteq [l,r]\)。若 \([l,r]\) 是好的,则 \([l',r']\) 必然也是好的。故我们可以使用双指针确定合法的 \([l,r]\) 对,时间复杂度 \(O(n^2)\)。

考虑对于一个固定的 \(l\),我们可以得到固定的序列 \(f\) 和固定的序列 \(g\) 。我们现在在不断改变 \(l\),则需要考虑序列 \(f\) 和序列 \(g\) 的变化,也就是讨论 \(f_i\) 和 \(g_i\) 的取值。


我们声称对于 \(f_i\) 和 \(g_i\),可能的取值只有 \(O(1)\) 种。

考虑对于 \(j < j+1\),\(p_j > p_{j+1}\),这两者必然有至少一个出现在递减子序列中。故对于满足条件的最大的 \(j\),\(p_j\) 和 \(p_{j+1}\) 都有可能对 \(f_i\) 产生贡献,且其一定最大,也就是说我们证明了 \(f_i\) 和 \(g_i\) 的取值只有 \(O(1)\) 种。


同时我们知道 \(f_i\) 的取值是只和 \(f_{i-1}\) 和 \(g_{i-1}\) 有关的,且随着 \(l\) 增大,\(f_i\) 的值也是不断增大的。同理,随着 \(l\) 增大,\(g\) 的值也是不断减小的。这意味着在移动 \(l\) 的过程中,动态更新 dp 数组,若 \(f_i\) 和 \(g_i\) 都没有变化就停止,此时复杂度为 \(O(n)\),可以通过。

//Ad astra per aspera
#include<iostream>
#include<cstdio>
#include<set>
using namespace std;
const int MAX=0x3f3f3f3f,MIN=-0x3f3f3f3f;
int p[200010],f[200010],g[200010];
int main(){
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&p[i]);
		f[i]=MIN;
		g[i]=MAX;
	}
	int maxn=0;
	long long ans=0;
	for(int i=1;i<=n;i++){
		f[i]=MAX;
		g[i]=MIN;
		maxn=max(maxn,i);
		for(int j=i+1;j<=n;j++){
			int lst_f=f[j],lst_g=g[j];
			if(p[j-1]<p[j]){
				f[j]=max(f[j],f[j-1]);
			}
			if(g[j-1]<p[j]){
				f[j]=max(f[j],p[j-1]);
			}
			if(p[j-1]>p[j]){
				g[j]=min(g[j],g[j-1]);
			}
			if(f[j-1]>p[j]){
				g[j]=min(g[j],p[j-1]);
			}
			if(f[j]!=MIN  ||  g[j]!=MAX){
				maxn=max(maxn,j);
			}
			if(lst_f==f[j]  &&  lst_g==g[j]){
				break;
			}
		}
		ans+=maxn-i+1;
	}
	printf("%lld",ans);
	return 0;
}
posted @ 2026-11-11 19:44  Oken喵~  阅读(6)  评论(0)    收藏  举报