[ARC125D] Unique Subsequence
场切模拟赛 T2。
找出
考虑 DP,根据某巨佬口中“很典的方式”定义状态
对于一个
同理对于一组
所以对于一个
考虑对区间求和进行优化,发现前缀和并不可行,所以我们使用树状数组,每次转移完后将
最后答案即
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN=2e5+10,MOD=998244353;
int n,a[MAXN],pre[MAXN],lst[MAXN];
long long f[MAXN],t[MAXN];
inline int lowbit(int x){return x&(-x);}
inline void change(int x,long long a)
{
while(x<=n) t[x]+=a,t[x]%=MOD,x+=lowbit(x);
return ;
}
inline long long query(int x)
{
long long ans=0;
while(x) ans+=t[x],ans%=MOD,x-=lowbit(x);
return ans;
}
int main()
{
cin.tie(0),cout.tie(0);
ios::sync_with_stdio(0);
cin>>n;
for(register int i=1;i<=n;++i) cin>>a[i],pre[i]=lst[a[i]],lst[a[i]]=i;//记录 pre[i]
for(register int i=1;i<=n;++i)
{
if(pre[i])
{
f[i]=(query(i-1)-query(pre[i]-1))%MOD;
change(pre[i],-f[pre[i]]);//这里要转移完成后再更新
}
else f[i]=(query(i-1)+1)%MOD;
change(i,f[i]);//将 i 号节点更新
}
cout<<(query(n)+MOD)%MOD<<'\n';return 0;
}