专栏文章
AGC020E Encoding Subsets 题解
AT_agc020_e题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minlvf5l
- 此快照首次捕获于
- 2025/12/02 04:32 3 个月前
- 此快照最后确认于
- 2025/12/02 04:32 3 个月前
首先考虑对于一个确定的长度为 的 串 ,如何求 的编码方式数。
设 表示 的编码方式数, 表示 缩成一个括号或单个字符的编码方式数。
对于 ,枚举 编码后第一个字符的来源,得到转移方程:
对于 ,枚举 的循环节 ,得到转移方程:
其中,,若 为 的循环节则 ,否则 。
直接计算即可得到 的编码方式数 。
接下来考虑如何计算长度为 的 串 的所有子集的编码方式数之和。
同理,设 表示 的所有子集的编码方式数之和, 表示 的所有子集的缩成一个括号或单个字符的编码方式数之和。
对于 ,仍然枚举 编码后第一个字符的来源,得到转移方程:
对于 ,同样枚举 的循环节 ,得到转移方程:
其中 表示,把 分成长度为 的 个 串,每个 串按位与的结果。
记忆化搜索即可。有效状态数并不多,足以通过。
Cconst int mod=998244353;
string s;
map <string,int> f,g;
void add(int &a,int b){
a+=b;
if(a>=mod) a-=mod;
}
int ad(int a,int b){
a+=b;
if(a>=mod) a-=mod;
return a;
}
int G(string s);
int F(string s){
if(s=="") return 1;
if(f.count(s)) return f[s];
int n=s.size(),ans=0;
for(int i=1;i<=n;i++) add(ans,1ll*G(s.substr(0,i))*F(s.substr(i,n-i))%mod);
return f[s]=ans;
}
int G(string s){
if(s=="") return 1;
if(s=="0") return 1;
if(s=="1") return 2;
if(g.count(s)) return g[s];
int n=s.size(),ans=0;
for(int d=1;d<n;d++){
if(n%d!=0) continue;
string t="";
for(int i=0;i<d;i++){
bool x=1;
for(int j=i;j<n;j+=d) x&=(s[j]=='1');
t+=x+'0';
}
add(ans,F(t));
}
return g[s]=ans;
}
void solve(){
cin>>s;
cout<<F(s)<<endl;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...