agc020E Encoding Subsets

31 篇文章 0 订阅

agc020E Encoding Subsets

  • 题意略。

Solution

  • 暴力递归即可。
  • 长度小的时候预处理DP即可。
  • 最多递归三层。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 105
#define maxm 14
#define ll long long 
#define uint unsigned int 
#define mo 998244353
using namespace std;

int n,i,j,k,a[maxm][maxn];
ll f[maxm+1][1<<maxm],g[maxm][maxn];
uint s[maxm][maxn];

void prepare(){
	f[0][0]=1;
	for(i=1;i<=maxm;i++) for(int S=0;S<1<<i;S++){
		f[i][S]=f[i-1][S^(S>>i-1<<i-1)]*((S>>i-1&1)+1)%mo;
		for(j=1;j*2<=i;j++){
			int T=S>>i-j;
			for(k=2*j;k<=i;k+=j){
				T&=S>>i-k;
				(f[i][S]+=f[i-k][S^(S>>i-k<<i-k)]*f[j][T])%=mo;
			}
		}
	}
}

ll doit(int d){
	memset(g[d],0,sizeof(ll)*(a[d][0]+1));
	for(int i=1;i<=a[d][0];i++) s[d][i]=s[d][i-1]<<1|a[d][i];
	g[d][0]=1;
	for(int i=1;i<=a[d][0];i++) {
		g[d][i]=g[d][i-1]*(a[d][i]+1)%mo;
		for(int j=1;j*2<=i;j++) if (j<=maxm){
			int T=s[d][i]^(s[d][i-j]<<j);
			for(int k=2*j;k<=i;k+=j){
				T&=s[d][i-k+j]^(s[d][i-k]<<j);
				(g[d][i]+=g[d][i-k]*f[j][T])%=mo;
			}
		} else {
			a[d+1][0]=j;
			for(int k=1;k<=j;k++) a[d+1][k]=a[d][i-j+k];
			for(int k=2*j;k<=i;k+=j){
				for(int l=1;l<=j;l++) a[d+1][l]&=a[d][i-k+l];
				(g[d][i]+=g[d][i-k]*doit(d+1))%=mo;
			}
		}
	}
	return g[d][a[d][0]];
}

int main(){
	freopen("ceshi.in","r",stdin);
	prepare();
	char ch=getchar();
	while (ch=='0'||ch=='1') a[0][++a[0][0]]=ch-'0',ch=getchar();
	if (a[0][0]<=maxm){
		k=0;for(i=a[0][0];i>=1;i--) k=(k<<1)|a[0][i];
		printf("%lld\n",f[a[0][0]][k]);
		return 0;
	}
	printf("%lld\n",doit(0));
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值