题解P17236【STA - R10 刷墙墙刷】
思路
若不对
于是我们重点考虑对
于是我们可以想到分奇数位和偶数位进行计数,分别提取 ? 的个数
但这还没完,我们还要考虑不操作时的
于是重点放在了如何分别统计偶数位和奇数位不合法的情况数。会发现直接用计数原理去想很难算,于是我们想到计数的两大利器“暴搜”和“动态规划”。这里我们用动态规划解决。设 ? 时可以
总的时间复杂度
代码
AC Code:(C++11)
#include<iostream>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
#include<numeric>
#include<vector>
#include<set>
#include<queue>
using namespace std;
const int Mod=998244353;
int n,flag1,flag2,ans01,ans02,ans11,ans12,ans;
string a,b,a0,b0,a1,b1;
int power25[1000005],power26[1000005],f[45],g[45];
void solve(string a,string b,int n,int &ans1,int &ans2) {
int cnt=0;
for(int i=0;i<n;i++) {
if(b[i]=='?')
cnt++;
else
if(i>0 && b[i]==b[i-1])
flag1=0;
else
if(a[i]!=b[i])
flag2=0;
}
ans1=power26[cnt]; ans2=0;
for(int i=0;i<26;i++)
f[i]=g[i]=0;
if(b[0]=='?') {
for(int i=0;i<26;i++)
f[i]=1;
}
else
f[b[0]-'a']=1;
for(int i=1;i<n;i++) {
int s=0;
for(int j=0;j<26;j++) {
(s+=f[j])%=Mod;
g[j]=0;
}
if(b[i]=='?') {
for(int j=0;j<26;j++)
g[j]=(s-f[j]+Mod)%Mod;
}
else
g[b[i]-'a']=(s-f[b[i]-'a']+Mod)%Mod;
for(int j=0;j<26;j++)
f[j]=g[j];
}
for(int i=0;i<26;i++)
(ans2+=f[i])%=Mod;
}
int main() {
ios::sync_with_stdio(0);
cout.tie(0);
cin>>n>>a>>b;
power25[0]=power26[0]=1;
for(int i=1;i<=n;i++) {
power25[i]=(25ll*power25[i-1])%Mod;
power26[i]=(26ll*power26[i-1])%Mod;
}
for(int i=0;i<n;i++)
if(i%2) {
a1+=a[i];
b1+=b[i];
}
else {
a0+=a[i];
b0+=b[i];
}
flag1=flag2=true;
solve(a0,b0,n-(n>>1),ans01,ans02);
solve(a1,b1,n>>1,ans11,ans12);
ans=(1ll*ans01*ans11)%Mod;
if(flag1) {
ans=(((ans-1ll*ans02*ans12)%Mod)+Mod)%Mod;
for(int i=0;i<n-2;i++)
if(a[i]==a[i+2]) {
flag2=0;
break;
}
if(flag2) {
ans++;
ans%=Mod;
}
}
cout<<ans<<'\n';
}
AC 记录