牛客寒假算法基础集训营6-B.价值序列

标签:数学,思维

在这里插入图片描述

思路

题目实际上可以转化为在不改变数组顺序的情况下删掉某些数,使得剩下的数组的价值与原数组相同,所以只需要找出有多少数可以删掉

先看一组例子,a1到a6分别为2,3,4,5,3,2,可以发现其中,a2=3,a3=4,a5=3能够删除,其实也就是单调区间中的数可以删掉,而区间边界,也就是拐点,是不能删掉的,因为删掉之后一定会导致价值变小(可以借助数轴理解),注意是变小,也就是说不存在前边删掉一个拐点使价值变小,然后后边又删掉一个拐点再将价值补回来这种情况,除了区间边界,数组的第一个和最后一个也不能删掉,这样只需要统计能删除的数的个数t,然后答案乘上2t(可以删也可以不删,每个数有两种选择)

还有一些特殊情况,那就是区间中会出现连续相等的数,比如4,2,2,2,4,这种情况3个2不能同时全部删除,所以这时候答案就要乘2t-1了

总结一下,对于1<i<=j<n,数组为a[i-1]<a[i]=…=a[j]<a[j+1]或者a[i-1]>a[i]=…=a[j]>a[j+1]的情况,a[i]到a[j]是可以全部删除的,其余情况就至少要保留一位数

代码实现

#include<stdio.h>
#include<iostream>
using namespace std;
const int N = 1e5 + 5;
const int mod = 998244353;
int t, book, n; 
int a[N];
long long qpow(int x){
	long long c = 1, d = 2;
	while(x){
		if(x&1) c = c*d%mod;
		d = d*d%mod;
		x = x >> 1;
	}
	return c;
}
int main(){
    cin >> t;
    while(t--){
    	long long ans = 1;
    	cin >> n;
    	for(int i = 1; i <= n; i++) cin >> a[i];
    	for(int i = 1; i <= n; i++){
    		int j = i;
    		while(a[i] == a[j+1]) j++;   //找区间连续相等的数
    		if(i >= 2 && j <= n - 1 && ((a[i] > a[i-1] && a[i] < a[j+1]) || (a[i] < a[i-1] && a[i] > a[j+1]))){  //全部能删掉的情况
    			ans = ans*qpow(j - i + 1)%mod;
			}else ans = ans*(qpow(j - i + 1) - 1)%mod;
			i = j;
		}
		cout << ans << "\n";
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值