11月10日联考 樱花月夜
Posted dftmr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了11月10日联考 樱花月夜相关的知识,希望对你有一定的参考价值。
题意经简化后就是询问多少个序列存在长度为3的回文串
可以用总方案减去不存在长度为3回文串的方案,即ai!=ai+2
考虑奇偶分治,最后将方案相乘
若一段数形如p,0,0,...,0,q,可以发现不存在长度为3的回文串的方案只与p和q是否相等和0的个数有关
令f[i]表示0的个数为i且p!=q的方案数,g[i]表示0的个数为i且p=q的方案数,这样就可以dp了
#include<bits/stdc++.h> using namespace std; const int M=998244353; int n,m,a[200005],b[200005],i,k; long long ans=1,s=1,p[200005],q[200005]; long long qpow(long long a,long long b){ long long s=a,ans=1; while(b){ if(b&1) ans=ans*s%M; s=s*s%M; b>>=1; } return ans; } void cnt(){ int i,t,j; for(i=1;i<=k;++i) if(b[i]!=0){ t=i; break; } if(i>k){ ans=ans*qpow(m-1,k-1)%M*m%M; return; } long long s=qpow(m-1,t-1); for(i=t;i<=k;){ for(j=i+1;b[j]==0&&j<=k;++j); if(j>k){ s=s*qpow(m-1,k-i)%M; break; } if(b[j]==b[i]) s=s*p[j-i]%M; else s=s*q[j-i]%M; i=j; } ans=ans*s%M; } int main(){ scanf("%d %d",&n,&m); for(i=1;i<=n;++i){ scanf("%d",&a[i]); if(a[i]==0) s=s*m%M; } p[1]=0;q[1]=1; for(i=2;i<=n;++i){ p[i]=q[i-1]*(m-1)%M; q[i]=(p[i-1]+q[i-1]*(m-2))%M; } for(i=1;i<=n;i+=2) b[++k]=a[i]; cnt(); k=0; for(i=2;i<=n;i+=2) b[++k]=a[i]; cnt(); cout<<((s-ans)%M+M)%M; }
以上是关于11月10日联考 樱花月夜的主要内容,如果未能解决你的问题,请参考以下文章
;~ 小部分AutoHotkey源代码片段测试模板2019年10月9日.ahk