[Codeforces Round #286 DIV1E (CF506E)] Mr. Kitayuta's Gift
2017-01-24 12:05
501 查看
题意
字符集大小26,给出一个串s(n=|s|≤200),现任意插入正好m个字符,询问构成回文串的个数,答案取模。题解
按照题解。1. dp(l,r,i)代表回文串的左i位可以匹配s的第l位,回文串的右i位可以匹配s的第r位。下面假设n+m为偶数
2. 将状态转移图画出来如图一(以串abaac为例),图中将存在24自环的点标为红色(Red),存在25自环的点标为绿色(Green)。设右上角的表示dp(1,n,0)的状态为START,从START走长度为n+m2的路径到达GOAL的方案数即为答案。
3. 可以发现这是一个DAG,故将所有的START→GOAL的链找出来,如图二。
4. 此时已经不关心原来字符串的数据了。又可以发现每一条链上,红点和绿点的顺序对答案没有影响,所以把红点放在前面,按红点数量排个序,再合并一下,如图三。
5. 显然,对于每一条链,红点数量为i,那么绿点数量为⌈n−i2⌉,这决定了最多有n条不同的链,每条链有倍数,下面用(R,G)来表示一条链,其中R是红点个数,G是绿点个数。
6. 每条(R,G)链可以拆分成(R+1,G),(R+1,G−1)两条链,如图四,第一个绿点将一条边指向了另一个绿点,这个新绿点跟原链的绿点环境相同,但是原来的绿点少了一条边变成了红点。
7. 将所有的(R,G)进行这种拆分,将其画在坐标图中,如图五,形成了点(⌈n2⌉,0),(⌈n2⌉+1,0),⋯,(n−1,0),(n,0),(n,1),⋯,(n,⌈n2⌉)并且能相应求出每种链有几条。
8. 把最终形成的链合并起来,如图六,这就是n+m为偶数的情形,用矩阵快速幂求解。
9. 那么n+m为奇数,呢?先求出来长度为n+m+12的答案,然后减去不合法的串,什么样的串不合法呢?所有在图1中走到表示状态dp(i,i+1)的点是不合法的。那么把这些点当做终点再进行一遍相同的dp,然后进行相同的步骤拆分链,合并链,构建自动机,矩阵快速幂。
代码
/// by ztx #include <cstdio> #include <cstring> #define Rep(i,l,r) for(i=(l);i<=(r);i++) #define rep(i,l,r) for(i=(l);i< (r);i++) #define Rev(i,r,l) for(i=(r);i>=(l);i--) #define rev(i,r,l) for(i=(r);i> (l);i--) #define mod 10007LL #define N 208LL #define M N*3/2 char s ; int f[N][N][N] = {0}; inline void dp(int n,int del=0) { int l, r, k; if (del) memset(f,0,sizeof f); Rev (l,n,1) Rep (r,l,n) { if (del) { if (l == r) continue; if (r == l+1) { f[l][r][0] = (s[l]==s[r]?1:0); continue; } } else if (l == r) { f[l][r][0] = 1; continue; } if (s[l] == s[r]) { if (l+1 <= r-1) Rep (k,0,n) f[l][r][k] = f[l+1][r-1][k]; if (r == l+1) f[l][r][0] = 1; } else { f[l][r][0] = 0; Rep (k,1,n) f[l][r][k] = (f[l+1][r][k-1]+f[l][r-1][k-1]) % mod; } } } inline int pow(int x,int p) { if (p <= 0) return 1; int ret = 1; for (; p; p>>=1, (x*=x)%=mod) if (p&1) (ret*=x)%=mod; return ret; } int n, T[M][M], A[M][M]; int io, jo; inline void ZERO(int A[M][M]) { Rep(io,1,n) Rep (jo,1,n) A[io][jo] = 0; } inline void ONE(int A[M][M]) { Rep(io,1,n) A[io][io] = 1; } int ic, jc; inline void COPY(int to[M][M],int from[M][M]) { Rep (ic,1,n) Rep (jc,ic,n) to[ic][jc] = from[ic][jc]; } int C[M][M], im, jm, km; inline void MUL(int A[M][M],int B[M][M]) { ZERO(C); Rep (im,1,n) Rep (jm,im,n) Rep (km,im,jm) (C[im][jm] += A[im][km]*B[km][jm]%mod) %= mod; COPY(A,C); } int X[M][M]; inline void POW(int A[M][M],int p) { COPY(X,A); for (ZERO(A), ONE(A); p; p>>=1, MUL(X,X)) if (p&1) MUL(A,X); } int g[N][N] ; inline int solve(int *f,int n,int len,int del=0) { if (del) memset(g,0,sizeof g); int i, j, h = (n+1)/2, GOAL = n+h+1; Rep (i,0,n) g[i][(n-i+1)/2] = f[i]; rep (i,0,n) Rep (j,1,h) { (g[i+1][j] += g[i][j]) %= mod; (g[i+1][j-1] += g[i][j]) %= mod; g[i][j] = 0; } ::n = n+h+1; ZERO(T), ZERO(A), A[1][1] = 1; rep (i,1,n+h) T[i][i+1] = 1; Rep (i,1,n+h) T[i][i] = (i<=n ? 24 : 25); Rep (i,h,n+h) T[i][GOAL] = (i<=n ? g[i][0] : g [i-n]); T[GOAL][GOAL] = (del ? 25 : 26); POW(T,len), MUL(A,T); return A[1][GOAL]; } int main() { int n, m, ans, len; scanf("%s%d", s+1, &m), n = strlen(s+1); dp(n); len = (n+m+1)/2; ans = solve(f[1] ,n,len); if ((n+m)%2 == 0 || n == 1) {} else if (n == 2) { if (s[1] == s[2]) ans = (ans-pow(25,len-1)+mod)%mod; } else { dp(n,1); ans = (ans-solve(f[1] ,n-2,len-1,1)+mod)%mod; } printf("%d\n", ans); return 0 ; }
相关文章推荐
- Codeforces Round #286 (Div. 2)-A. Mr. Kitayuta's Gift
- Codeforces Round #286 (Div. 2) A. Mr. Kitayuta's Gift
- Codeforces Round #286 (Div. 2) A - Mr. Kitayuta's Gift ( 暴力枚举)std:string::insert
- Codeforces Round #286 (Div. 2) D. Mr. Kitayuta's Technology 强连通分量 有向图求环
- Codeforces Round #286 (Div. 1) B. Mr. Kitayuta's Technology (强连通分量)
- CF 505A(Mr. Kitayuta's Gift-回文串)
- Codeforces Round #286 (Div. 2) B. Mr. Kitayuta's Colorful Graph +foyd算法的应用
- Codeforces Round #286 (Div. 1) B. Mr. Kitayuta's Technology (强连通分量)
- Codeforces Round #286 (Div. 2) C. Mr. Kitayuta, the Treasure Hunter——dp
- Codeforces Round #286 (Div. 2) C. Mr. Kitayuta, the Treasure Hunter+dp+优化
- 【Codeforces 506E】Mr.Kitayuta’s Gift&&【BZOJ 4214】黄昏下的礼物 dp转有限状态自动机+矩阵乘法优化
- codeforces #286 A. Mr. Kitayuta's Gift
- #286 (Div. 2) C. Mr. Kitayuta, the Treasure Hunter
- Codeforces Round #286 (Div. 1) D. Mr. Kitayuta's Colorful Graph 高维并查集,STL连招
- Codeforces Round #286 Div.1 A Mr. Kitayuta, the Treasure Hunter --DP
- A. Mr. Kitayuta's Gift
- CF - 286 - div2 - C - Mr. Kitayuta, the Treasure Hunter (DP)
- [Codeforces Round #286 DIV1B (CF506B)] Mr. Kitayuta's Technology
- Codeforces Round #286 (Div. 2) C Mr. Kitayuta, the Treasure Hunter ( DP )
- Codeforces Round #286 (Div. 2) B. Mr. Kitayuta's Colorful Graph