题解 路人女主
这世界上最可恶的事情就是打表题打出来表了没找到规律
规律是
证明不会
求这个东西直接求会算重,减去即可
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 2000010
#define fir first
#define sec second
#define ll long long
#define ull unsigned long long
//#define int long long
int n;
char s[N], t[N];
const ll mod=998244353;
inline void md(ll& a, ll b) {a+=b; a=a>=mod?a-mod:a;}
namespace force{
bool vis_s[N], vis_t[N];
int f[18][18], len, top, ans;
pair<int, int> sta[N];
int lcs() {
// need hash
memset(f, 0, sizeof(f));
for (int i=1; i<=len; ++i)
for (int j=1; j<=len; ++j)
f[i][j]=max(max(f[i-1][j], f[i][j-1]), f[i-1][j-1]+(s[i]==t[j]));
return f[len][len];
}
void dfs(int u) {
if (u>top) {
if (lcs()==n) ++ans;
// if (lcs()==n) {
// cout<<"lcs: "<<lcs()<<endl;
// cout<<"st: "<<endl;
// cout<<s+1<<endl;
// cout<<t+1<<endl;
// }
return ;
}
for (char c='A'; c<='C'; ++c) {
// could deal with sta[u].sec==1
if (sta[u].fir==1 && (s[sta[u].sec-1]==c||(vis_s[sta[u].sec+1]&&s[sta[u].sec+1]==c))) continue;
if (sta[u].fir==2 && (t[sta[u].sec-1]==c||(vis_t[sta[u].sec+1]&&t[sta[u].sec+1]==c))) continue;
if (sta[u].fir==1) s[sta[u].sec]=c;
else t[sta[u].sec]=c;
dfs(u+1);
}
}
void solve() {
len=n<<1|1; top=ans=0;
for (int i=1; i<=len; ++i)
if (s[i]=='?') sta[++top]={1, i};
else vis_s[i]=1;
for (int i=1; i<=len; ++i)
if (t[i]=='?') sta[++top]={2, i};
else vis_t[i]=1;
for (int i=2; i<=len; ++i) if (s[i]!='?'&&s[i-1]!='?'&&s[i]==s[i-1]) {puts("0"); return ;}
for (int i=2; i<=len; ++i) if (t[i]!='?'&&t[i-1]!='?'&&t[i]==t[i-1]) {puts("0"); return ;}
dfs(1);
cout<<ans<<endl;
}
}
// namespace task1{
// int len;
// ll f[20][20][20][3][3], ans;
// void solve() {
// len=n<<1|1; ans=0;
// for (int i=1; i<=len; ++i) if (s[i]!='?') s[i]-='A';
// for (int i=1; i<=len; ++i) if (t[i]!='?') t[i]-='A';
// for (int now_s=0; now_s<=3; ++now_s)
// for (int now_t=0; now_t<=3; ++now_t)
// ++f[1][1][now_s==now_t][now_s][now_t];
// for (int i=2; i<=len; ++i)
// for (int j=2; j<=len; ++j)
// for (int k=0; k<=min(i, j); ++k)
// for (int now_s=0; now_s<=3; ++now_s) if (s[i]==now_s||s[i]=='?')
// for (int now_t=0; now_t<=3; ++now_t) if (t[i]==now_t||t[i]=='?')
// for (int lst_s=0; lst_s<=3; ++lst_s) if (now_s!=lst_s)
// for (int lst_t=0; lst_t<=3; ++lst_t) if (now_t!=lst_t) {
// md(f[i][j][k][now_s][now_t], f[i-1][j][k][lst_s][lst_t]);
// md(f[i][j][k][now_s][now_t], f[i][j-1][k][lst_s][lst_t]);
// if (now_s==now_t) {
// if (k) md(f[i][j][k][now_s][now_t], f[i-1][j-1][k-1][lst_s][lst_t]);
// }
// else md(f[i][j][k][now_s][now_t], f[i-1][j][k][lst_s][lst_t]);
// }
// }
// }
namespace task{
ll ans;
char c[4];
int sa_pre[N], sb_pre[N], sa_suf[N], sb_suf[N], ta_pre[N], tb_pre[N], ta_suf[N], tb_suf[N], len;
void solve1(char a, char b, char c) {
ll dlt=1;
char now=a, lst=b;
for (int i=1; i<=len; ++i,swap(now, lst))
if (s[i]!='?' && s[i]!=now) return ;
for (int i=1; i<=len; ++i) {
if (i&1) {if (t[i]!='?'&&t[i]!=c) return ;}
else {
if (t[i]==c) return;
if (t[i]=='?') dlt=(dlt<<1)%mod;
}
}
ans=(ans+dlt)%mod;
}
void solve2(char a, char b, char c) {
// cout<<"solve2: "<<a<<' '<<b<<' '<<c<<endl;
for (int i=2; i<=len; i+=2) {
if (s[i]!='?'&&s[i]!=c) return ;
if (t[i]!='?'&&t[i]!=c) return ;
}
for (int i=1; i<=len; i+=2) if (s[i]==c||t[i]==c) return ;
for (int i=1; i<=len; ++i) {
sa_pre[i]=sa_pre[i-1]+(s[i]==a);
sb_pre[i]=sb_pre[i-1]+(s[i]==b);
ta_pre[i]=ta_pre[i-1]+(t[i]==a);
tb_pre[i]=tb_pre[i-1]+(t[i]==b);
}
sa_suf[len+1]=sb_suf[len+1]=ta_suf[len+1]=tb_suf[len+1]=0;
for (int i=len; i; --i) {
sa_suf[i]=sa_suf[i+1]+(s[i]==a);
sb_suf[i]=sb_suf[i+1]+(s[i]==b);
ta_suf[i]=ta_suf[i+1]+(t[i]==a);
tb_suf[i]=tb_suf[i+1]+(t[i]==b);
}
for (int i=1; i<len; i+=2) if (!sb_pre[i]&&!sa_suf[i+1]&&!ta_pre[i]&&!tb_suf[i+1]) ans=(ans+1)%mod; //, cout<<"at: "<<i<<endl;
// cout<<1<<endl;
}
// void solve3(char a, char b, char c, int d) {
// if (d==a) return ;
// char now=a, lst=b;
// for (int i=1; i<=len; ++i,swap(now, lst))
// if (s[i]!='?' && s[i]!=now) return ;
// for (int i=1; i<=len; ++i) {
// if (i&1) {if (t[i]!='?'&&t[i]!=c) return ;}
// else {
// if (t[i]!='?'&&t[i]!=d) return ;
// // if (s[i]!='?'&&s[i]!=d) return ;
// }
// }
// // now=a, lst=b;
// // for (int i=1; i<=len; ++i,swap(now, lst))
// // if (t[i]!='?' && t[i]!=now) return ;
// // for (int i=1; i<=len; ++i) {
// // if (i&1) {if (s[i]!='?'&&s[i]!=c) return ;}
// // else {if (s[i]!='?'&&s[i]!=d) return ;}
// // }
// ans=(ans-1)%mod;
// }
void solve3(char a, char b, char c) {
char now=a, lst=b;
for (int i=1; i<=len; ++i,swap(now, lst))
if (s[i]!='?' && s[i]!=now) return ;
now=c, lst=b;
for (int i=1; i<=len; ++i,swap(now, lst))
if (t[i]!='?' && t[i]!=now) return ;
ans=(ans-1)%mod;
}
void solve() {
len=n<<1|1; ans=0;
for (char i='A'; i<='C'; ++i) c[i-'A'+1]=i;
do {solve1(c[1], c[2], c[3]); solve2(c[1], c[2], c[3]);} while (next_permutation(c+1, c+3+1));
for (char i='A'; i<='C'; ++i) c[i-'A'+1]=i;
for (int i=1; i<=len; ++i) swap(s[i], t[i]);
do {solve1(c[1], c[2], c[3]); solve3(c[1], c[2], c[3]);} while (next_permutation(c+1, c+3+1));
cout<<(ans%mod+mod)%mod<<endl;
}
}
signed main()
{
freopen("a.in", "r", stdin);
freopen("a.out", "w", stdout);
int T;
scanf("%d", &T);
while (T--) {
scanf("%d%s%s", &n, s+1, t+1);
// force::solve();
task::solve();
}
return 0;
}