思路
如果 ai=aj,且bi=bj时,可知b[i]=b[i+1]=…=b[j],对b来说 [i,j] 这个区间的值是一致的
用l[x],r[x]分别代表,x这个值的边界位置(也就是最左和最右位置) 则[l[x],r[x]]这个区间是一致的
如果两个线段相交,那么相交的两个线段必然都一致
设y是不相交线段的个数,ans是解
那么 ans=2^y%mod
解决方案
/*
@description:
@author: universal42@163.com
@solution:
后一项等于当前项,或者比当前项大于1
b序列使一个单调递增的序列
*/
#include<map>
#include<queue>
#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define LOCAL
#define cls ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define Mod 998244353
#define ll long long int
#define mset(a,b) memset(a,b,sizeof(a))
#define INF 1e9
const int maxn=2e5+5;
int a[maxn];
int n;
map<int,int> r;//记录数字x最右边位置
ll pow_mod(ll a,ll b){//a^b%mod
ll res=1;
while(b){
if(b&1) res=(res*a)%Mod;
b>>=1;
a=a*a%Mod;
}
return res;
}
ll getSegNum(){//获取不相交线段个数
/*
初始化线段个数为n,如果两个线段相交,那么用n减去 相交线段的最右边的线段的右端点减去第一个线段的左端点再加一 ,就是不相交线段的个数
*/
int ans=n;
int last=-1;
int start=0;
for(int i=0;i<n;i++){
if(r[a[i]]!=i){//右边端点不是自身,也就是说这个值不是单点
last=r[a[i]];
start=i;
for(int j=start+1;j<=last;j++){
if(r[a[j]]>r[a[start]]){//该区间相交
start=j;
last=r[a[j]];
}
}
ans=ans-last+i;
i=last;
}
}
return ans;
}
int main() {
//cls;
#ifdef LOCAL
freopen("in.in","r",stdin);
#endif // LOCAL
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
r[a[i]]=i;
}
ll cnt=getSegNum();
ll ans=pow_mod(2,cnt-1);
printf("%lld\n",ans);
return 0;
}