题解 路人女主

传送门

这世界上最可恶的事情就是打表题打出来表了没找到规律

规律是
image
证明不会
求这个东西直接求会算重,减去即可

点击查看代码
#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;
}
posted @ 2022-05-05 08:50  Administrator-09  阅读(3)  评论(0编辑  收藏  举报