题意:给定一个串,把串分为偶数段

假设分为\(s_1,s_2,s_3....s_k\)

求满足$ s_1=s_k,s_2=s_{ k-1 }... $的方案数模\(10^9+7\)

\(|S|\leq 10^6\)

首先想到将原串变为\(s_1 s_n s_2 s_{n-2}...\) 这样问题变成了求将新串分成任意个偶数长度回文串的方案数

对于这个问题,我们先给出两个结论

\(1.\)一个回文串S的后缀\(T\)如果是回文串等价于\(T\)是\(S\)的$border $

\(2.\)将一个串\(S\)的所有\(borde\)r按长度从小到大排序后,能形成\(log\)个等差数列

设\(f_i\)表示\(s[1...i]\)分成回文串的方案数,\(g_p\)表示回文串\(p\)在\(s[1...i]\)中最后一次出现且此时为等差数列\((str_1,str_2,str_3...,p)\)的最后一项时的\(\sum_{str_i}f_{i-|str_i|}\)

对于一个等差序列,设当前节点为末项的等差数列有\(b_1,b_2,b_3\),公差为\(d\),其中\(|b1|>|b2|>|b3|\)那么有\(g_p=f_{i-b1}+f_{i-b2}+f_{i-b3}\)

根据结论\(1\),不难发现\(S_{i-b2,i-d}=S_{i-b3,i},S_{i-b1,i-d}=S_{i-b2,i}\),那么在\(g_{fail[p]}\)中就已经包含了\(f_{i-b1}\)和\(f{i-b2}\),只要把\(f_{i-b3}\)加上就好了

#include<bits/stdc++.h>
using namespace std;
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
#define pa pair<int,int>
#define mod 1000000007
#define ll long long
#define mk make_pair
#define pb push_back
#define lb double
#define fi first
#define se second
#define cl(x) memset(x,0,sizeof x)
#ifdef Devil_Gary
#define bug(x) cout<<(#x)<<" "<<(x)<<endl
#define debug(...) fprintf(stderr, __VA_ARGS__)
#else
#define bug(x)
#define debug(...)
#endif
const int INF = 0x7fffffff;
const int N=1e6+5;
/*
char *TT,*mo,but[(1<<15)+2];
#define getchar() ((TT==mo&&(mo=(TT=but)+fread(but,1,1<<15,stdin),TT==mo))?-1:*TT++)//*/
inline int read(){
int x=0,rev=0,ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')rev=1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return rev?-x:x;
}
int n,lst,cnt=1,id[N],nxt[N],c[N][26],fail[N],len[N],f[N],g[N],diff[N];
char s[N],ss[N];
int extend(int x,int n){
int p=lst;
while(s[n-len[p]-1]!=s[n]) p=fail[p];
if(!c[p][x]){
int now=++cnt,k=fail[p];
len[now]=len[p]+2;
while(s[n-len[k]-1]!=s[n]) k=fail[k];
fail[now]=c[k][x],c[p][x]=now;
diff[now]=len[now]-len[fail[now]];
if(diff[now]==diff[fail[now]]) nxt[now]=nxt[fail[now]];
else nxt[now]=fail[now];
}
return lst=c[p][x];
}
int main(){
#ifdef Devil_Gary
freopen("in.txt","r",stdin);
#endif
scanf("%s",ss+1),n=strlen(ss+1);
for(int i=1,j=0;i<=n;i+=2) s[i]=ss[++j];
for(int i=2,j=n+1;i<=n;i+=2) s[i]=ss[--j];
fail[0]=fail[1]=1,len[1]=-1,f[0]=1;
for(int i=1;i<=n;i++) id[i]=extend(s[i]-'a',i);
for(int i=1;i<=n;i++){
for(int j=id[i];j;j=nxt[j]){
g[j]=f[i-len[nxt[j]]-diff[j]];
if(diff[j]==diff[fail[j]]) (g[j]+=g[fail[j]])%=mod;
if(!(i&1)) (f[i]+=g[j])%=mod;
}
}
printf("%d\n",f[n]);
}

Codeforces 932G Palindrome Partition 回文树+DP的更多相关文章

  1. Codeforces 932G Palindrome Partition - 回文树 - 动态规划

    题目传送门 通往???的传送点 通往神秘地带的传送点 通往未知地带的传送点 题目大意 给定一个串$s$,要求将$s$划分为$t_{1}t_{2}\cdots t_{k}$,其中$2\mid k$,且$ ...

  2. CF932G Palindrome Partition(回文自动机)

    CF932G Palindrome Partition(回文自动机) Luogu 题解时间 首先将字符串 $ s[1...n] $ 变成 $ s[1]s[n]s[2]s[n-1]... $ 就变成了求 ...

  3. Palindrome Partition CodeForces - 932G 回文树+DP+(回文后缀的等差性质)

    题意: 给出一个长度为偶数的字符串S,要求把S分成k部分,其中k为任意偶数,设为a[1..k],且满足对于任意的i,有a[i]=a[k-i+1].问划分的方案数. n<=1000000 题解: ...

  4. Palisection(Codeforces Beta Round #17E+回文树)

    题目链接 传送门 题意 给你一个串串,问你有多少对回文串相交. 思路 由于正着做不太好算答案,那么我们考虑用总的回文对数减去不相交的回文对数. 而不相交的回文对数可以通过计算以\(i\)为右端点的回文 ...

  5. HDU 6599 I Love Palindrome String (回文树+hash)

    题意 找如下子串的个数: (l,r)是回文串,并且(l,(l+r)/2)也是回文串 思路 本来写了个回文树+dfs+hash,由于用了map所以T了 后来发现既然该子串和该子串的前半部分都是回文串,所 ...

  6. 【CF932G】Palindrome Partition 回文自动机

    [CF932G]Palindrome Partition 题意:给你一个字符串s,问你有多少种方式,可以将s分割成k个子串,设k个子串是$x_1x_2...x_k$,满足$x_1=x_k,x_2=x_ ...

  7. BZOJ4044: [Cerc2014] Virus synthesis(回文树+DP)

    Description Viruses are usually bad for your health. How about fighting them with... other viruses? ...

  8. 2019牛客暑期多校训练营(第六场)Palindrome Mouse 回文树+dfs

    题目传送门 题意:给出一个字符串,将字符串中所有的回文子串全部放入一个集合里,去重后.问这个集合里有几对<a,b>,使得a是b的子串. 思路:一开始想偏了,以为只要求每个回文串的回文后缀的 ...

  9. @codeforces - 932G@ Palindrome Partition

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个字符串 s,求有多少种方案可将其划分成偶数个段 \(p_ ...

随机推荐

  1. eclipse配置JDK

    配置JDK 注意:此处配置的是JDK安装路径,不是JRE!!!

  2. mtk 无线配置文件生效过程

    openwrt 下无线接口的配置文件位于 /etc/config/wirless 中. 启动 /sbin/wifi 脚本后,生效过程如下: (1)通过 uci2dat 工具生成所需要的 .dat文件 ...

  3. vue系列之项目打包

    vue完成项目后,如何打包成静态文件,并且用Node调试 打包 1.修改config里面的index.js里面的productionSourceMap为false,默认情况是true(true代表打包 ...

  4. jquery submit ie6下失效的原因分析及解决方法

    ie6中, $('a.btn').click(function(){ form.submit(); }) 点击失效: 分析: 微软低版本浏览器会先执行link标签的自身事件也就是href事件,这样就中 ...

  5. 目标检测的图像特征提取之(一)HOG特征(转)

    看过很多介绍HOG的博文,讲的最清楚的是这位博主:http://blog.csdn.net/zouxy09/article/details/7929348 代码如下: #include <ope ...

  6. wampserver修改端口号后,phpMyAdmin进不去,需要修改相关配置文件

    一.修改Apache端口 1.在界面中选Apache,弹出隐藏菜单选项,打开配置文件httpd.conf: 2.找到 Listen 80: 3.将 80 改成 8080(当然自己也可以设定别的不使用的 ...

  7. *****hibernate主键生成

    一.主键主键是关系数据库中的一个基本概念,它用来保证记录的唯一性主键都是没有业务含义的,所以开发 者不会.也不需要,显示地设置实体对象的主键值.但是对于数据库来说,主键是必须的 Hibernate内置 ...

  8. javafx实现模态/模式窗口

    import javafx.stage.*; import javafx.scene.*; import javafx.scene.paint.Color; import javafx.scene.c ...

  9. 开始写博客,学习Linq(2)

    linq的功能是什么? 它将极大地改变应用程序或组件处理数据的方式.这是第一个功能. LINQ to Objects.LINQ to SQL和LINQ to XML,是LINQ三大主要功能,当然LIN ...

  10. binlog和redo log日志提交

    组提交(group commit)是MYSQL处理日志的一种优化方式,主要为了解决写日志时频繁刷磁盘的问题.组提交伴随着MYSQL的发展不断优化,从最初只支持redo log 组提交,到目前5.6官方 ...