发现子串必须是奇数长度,不然没有中间元素,其次子串是连续的子序列,所以对于每个 C 字符都左右扩展找到最长的子串个数就好了。
代码部分
▶
AcCode
1 2 3 4 5 6 7 8 9 10 11 12 13
voidsolve( ){ string s; cin >> s; ll ans = 0; int n = s.size( ); for( int i = 0; i < n; ++ i ) { if( s[i] == 'C' ) { ll cnt = min( i, n - i - 1 ); // 左边 i | 右边 n - 1 - i ans += cnt + 1; // 0->cnt } } cout << ans << '\n'; }
for( int i = 1; i <= q; ++ i ) { int a, b; cin >> a >> b; int cur = *mid; s.insert( a ), s.insert( b ); if( a < cur && b < cur ) mid --; elseif( a >= cur && b >= cur ) mid ++; cout << *mid << '\n'; } }
ll qpow( ll a, ll k, ll mod ){ ll res = 1; a %= mod; for( ; k; k >>= 1, a = a * a % mod ) if( k & 1 ) res = res * a % mod; return res; }
ll fac[maxn], invfac[maxn]; voidinit( int N ){ fac[0] = 1; for( int i = 1; i <= N; i ++ ) fac[i] = fac[i - 1] * i % mod; invfac[N] = qpow( fac[N], mod - 2, mod ); for( int i = N - 1; i >= 0; i -- ) invfac[i] = invfac[i + 1] * ( i + 1 ) % mod; }
ll nCr( int n, int r ){ if( n < r ) return0; return fac[n] * invfac[n - r] % mod * invfac[r] % mod; } // 略去前面预处理 nCr 相关的模板。最后的调用 nCr(n, r) 就是 n 个里面选 r 个。 // 最后想了想还是加上吧,我也不知道为什么
首先是给了很多个模式串,首选考虑 AC自动机,从而实现对禁止字符串的识别。我们在自动机上走一步,就相当于在字符串末尾追加一个字母。(注:这里在构建 fail 指针时,如果一个节点 u 的 fail 指针指向了非法节点,就意味着当前前缀的某个后缀是非法的,那么当前 u 这一点也必须设置成非法的),如下:
structMatrix { ll m[maxsz][maxsz]; int sz; Matrix( int _sz = 0 ) : sz( _sz ) { memset( m, 0, sizeof m ); } voidinit( ){ for( int i = 1; i <= sz; ++ i ) m[i][i] = 1; } friend Matrix operator *( Matrix a, Matrix b ) { Matrix res( a.sz ); for( int i = 1; i <= a.sz; ++ i ) { for( int j = 1; j <= b.sz; ++ j ) { for( int k = 1; k <= a.sz; ++ k ) { res.m[i][j] = ( res.m[i][j] + a.m[i][k] * b.m[k][j] % mod ) % mod; } } } return res; } };
Matrix mqpow( Matrix a, ll k ){ Matrix res( a.sz ); res.init( ); for( ; k; k >>= 1, a = a * a ) if( k & 1 ) res = res * a; return res; } // 上面是我的矩阵快速幂板子,为什么要贴出来呢?我也不知道
voidsolve( ){ ll n, k; actree.init( ); // 0-index
cin >> n >> k; for( int i = 1; i <= k; ++ i ) { cin >> s[i]; actree.insert( s[i] ); } actree.build( ); int sz = actree.tot + 1;
Matrix A( sz ); // 1-index for( int u = 0; u <= actree.tot; ++ u ) { if( actree.bad[u] ) continue; for( int ch = 0; ch < 26; ++ ch ) { int v = actree.ch[u][ch]; if( !actree.bad[v] ) A.m[v+1][u+1] ++; // 0->1 } }
Matrix res = mqpow( A, n ); ll ans = 0; for( int i = 0; i <= actree.tot; ++ i ) { if( actree.bad[i] ) continue; ans = ( ans + res.m[i+1][1] ) % mod; // 0->1 } cout << ans << '\n'; }