CF2069C Beautiful Sequence 解题报告
题目传送门
题目大意
有一个只有
解题思路
对于只有
对于每一个
其中
显然这个式子是需要
考虑将第一个
- 用一个
3 的个数的后缀cnt3 代表a_i 后面的3 的个数,显然每遇到一个3 ,cnt3 的个数减一; - 每遇到一个
2 ,对于这个2 后面的每个3 ,它对答案的贡献都要从2^{cnt2}-1 变为2^{cnt2-1}-1 ,操作为-1 再\times \frac{1}{2} 。则遇到这个2 ,对ans1 的总变化为-cnt3 再\times \frac{1}{2} 。 - 每遇到一个
1 ,此时的ans1 就是它对答案的变化,直接加到答案上即可。
预处理求出
总时间复杂度
AC Code
#include<bits/stdc++.h>
#define int long long
#define mod 998244353
using namespace std;
int n;
int a[200005];
int re()//快读
void wr(int x)//快写
int ksm(int a,int b)//快速幂
{
int ans=1;
for(;b;a*=a,a%=mod,b>>=1)
if(b&1)
ans*=a,ans%=mod;
return ans;
}
signed main(){
int T=re();
while (T--)
{
int n=re(),ans=0;
for(int i=1;i<=n;i++)
a[i]=re();
int cnt2=0,cnt3=0;
int ans1=0,pos=n;//pos为第一个1的位置
for(int i=1;i<=n;i++)
if(a[i]==1)
{
pos=i;
break;
}
for(int i=pos;i<=n;i++)
if(a[i]==2)
cnt2++;
else if(a[i]==3)
{
ans1+=ksm(2,cnt2)-1;//这个3对答案的贡献
ans1%=mod;
cnt3++;
}
ans+=ans1;
for(int i=pos+1;i<=n;i++)
if(a[i]==2)//遇到2
ans1-=cnt3,ans%=mod,ans+=mod,ans%=mod,ans1*=ksm(2,mod-2),ans1%=mod;
else if(a[i]==1)
ans+=ans1,ans%=mod;
else
cnt3--;//遇到3
wr(ans),puts("");
}
return 0;
}