1 条题解

  • 0
    @ 2026-5-2 11:02:30

    题目大意

    给你 nn 个数,问你这 nn 个数中有多少个双调序列,也就是说前半段严格上升,后半段严格下降。

    具体思路

    我们可以将一个双调序列拆分成两个部分,分别是左边的上升序列和右边的下降序列。我们用两个数组 fff2f2 分别表示以 ii 结尾的上升序列有多少个和以 ii 开头的下降序列有多少个。

    如何计算 fff2f2 呢?首先是 fff1f_1 显然是 11,接着从左往右推,如果 ai>ai1a_i>a_{i-1}fif_i 就是 fi1+1f_{i-1}+1,否则 fif_i 就为 11

    同理,f2n=1f2_n=1,从右往左推.如果 ai>ai1a_i>a_{i-1}f2if2_i 就是 f2i+1+1f2_{i+1}+1,否则 f2if2_i 就为 11

    那么,对于每一个 ii,以 ii 为峰值的双调序列个数就是 fi×f2if_i\times f2_i,最后再累加起来就行。

    完整代码

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    int a[300005];
    int f[300005],f2[300005];
    signed main(){
    	int n,ans=0;
    	cin>>n;
    	for(int i=1;i<=n;i++)cin>>a[i];
    	f[1]=f2[n]=1;//初始化
    	for(int i=2;i<=n;i++){
    		if(a[i]>a[i-1])f[i]=f[i-1]+1;
    		else f[i]=1;
    	}//计算f。
    	for(int i=n-1;i>0;i--){
    		if(a[i]>a[i+1])f2[i]=f2[i+1]+1;
    		else f2[i]=1;
    	}//计算f2。
    	for(int i=1;i<=n;i++)ans+=f[i]*f2[i];//相乘。
    	cout<<ans;
    	return 0;//完结撒花!
    }
    
    • 1

    信息

    ID
    10304
    时间
    1000ms
    内存
    512MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者