AT4108 [ARC094D] Normalization
Posted 275307894a
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AT4108 [ARC094D] Normalization相关的知识,希望对你有一定的参考价值。
题面传送门
盲猜了个结论然后居然对了。
如果我们把a看成\\(0\\),b看成\\(1\\),c看成\\(2\\),容易发现一次变换后所有值加和\\(\\mod 3\\)的值不变。
然后稍微想一想就可以发现除了\\(T=S\\)之外,\\(T\\)中一定至少一个相邻两字符相同。
所以这个是必要条件。
然后我猜这是个充分条件。
所以基础dp即可。
code:
#include <vector>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#include<algorithm>
#include<bitset>
#include<set>
#include<map>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define l(x) x<<1
#define r(x) x<<1|1
#define re register
#define ll long long
#define db long double
#define N 200000
#define eps (1e-14)
#define mod 998244353
using namespace std;
int n,ans,tot,flag=1;ll f[N+5][3][3],g[N+5][3];char c[N+5];string s;map<string,int> fl;
I void dfs(){
if(fl[s]) return;fl[s]=1;ans++;int i;char c;
for(i=0;i<n-1;i++){
if(s[i]!=s[i+1]) c=s[i],s[i]=s[i+1]=s[i]^s[i+1],dfs(),s[i]=c,s[i+1]^=s[i];
}
}
int main(){
freopen("fiveopen.in","r",stdin);freopen("fiveopen.out","w",stdout);
re int i,j,h,k;scanf("%s",c+1);n=strlen(c+1);
if(n<=3){
for(i=1;i<=n;i++) s+=c[i]-\'a\'+1;dfs();printf("%d\\n",ans);
return 0;
}
for(i=1;i<=n;i++) c[i]-=\'a\',ans+=c[i];ans%=3;f[1][1][1]=f[1][0][0]=f[1][2][2]=1;
for(i=1;i<n;i++) if(c[i]^c[i+1]){flag=0;break;} if(flag){printf("1\\n");return 0;}
for(i=1;i<=n;i++){
for(j=0;j<=2;j++){
for(h=0;h<=2;h++){
g[i][j]+=g[i-1][(j-h+3)%3]+f[i-1][(j-h+3)%3][h];
for(k=0;k<=2;k++) k^h&&(f[i][j][h]+=f[i-1][(j-h+3)%3][k]);f[i][j][h]%=mod;
}
g[i][j]%=mod;
}
}
for(flag=1,i=1;i<n;i++)if(c[i]==c[i+1]) flag=0;printf("%lld\\n",(flag+g[n][ans])%mod);
}
以上是关于AT4108 [ARC094D] Normalization的主要内容,如果未能解决你的问题,请参考以下文章
[Arc068D/At2299] Card Eater - 结论