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 ) ) ;
}