【题目大意】

在一个仅仅含有a,b的字符串里选取一个子序列,使得:

1.位置和字符都关于某条对称轴对称;

2.不能是连续的一段。

【思路】

不连续的回文串的个数=总的回文串个数-连续回文串的个数。

后者可以用manacher在O(n)时间里面求出。求的是个数不是最长串,和之前写的几道不怎么一样,注意一下。

求总的回文串个数稍微复杂一些。我们用f[i]表示以i为对称中心,两边有多少个对称的字符。对于每个中心i我们有(2^f[i])-1种方案 答案即Σ[1<=i<=n*2+1]((2^f[i])-1)。

显然f[i]=(Σ[1<=j<=i-1]bool(str[j]==str[i-j]))+1>>1。

至于如何求出f[i],我们分别用a[]、b[]记录下每一位是否出现'a'或'b'。比如ababa这样一个数组,a={10101},b={01010}

a[]的卷积就是'a'的贡献,b[]的卷积就是'b'的贡献,两者相加+1再除以2即可。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<complex>
#include<cmath>
#define pi acos(-1)
using namespace std;
const int MAXN=+;
const int MOD=;
typedef complex<double> com;
typedef long long ll;
com a[MAXN],b[MAXN],c[MAXN];
int ina[MAXN],inb[MAXN],f[MAXN],p[MAXN],Rev[MAXN],m,n,L;
char s[MAXN],str[MAXN];
void get_bit(){for (n=,L=;n<m;n<<=) L++;}
void get_Rev(){for (int i=;i<n;i++) Rev[i]=(Rev[i>>]>>)|((i&)<<(L-));} void FFT(com* a,int flag)
{
for (int i=;i<n;i++)if(i<Rev[i])swap(a[i],a[Rev[i]]);
for (int i=;i<n;i<<=)
{
com wn(cos(pi/i),flag*sin(pi/i));
for (int j=;j<n;j+=(i<<))
{
com w(,);
for (int k=;k<i;k++,w*=wn)
{
com x=a[j+k],y=w*a[j+k+i];
a[j+k]=x+y;
a[j+k+i]=x-y;
}
}
}
if (flag==-) for (int i=;i<n;i++) a[i]/=n;
} int manacher()
{
str[]='$';
str[]='#';
for (int i=,j=;s[i+];i++)
{
str[++j]=s[i+];
str[++j]='#';
}
int mx=,mxid=,ret=;
memset(p,,sizeof(p));
for (int i=;str[i];i++)
{
if (mx>i) p[i]=(p[*mxid-i]<(mx-i)?p[*mxid-i]:(mx-i));
else p[i]=;
while(str[i-p[i]]==str[i+p[i]]) p[i]++;
if (i+p[i]>mx)
{
mx=i+p[i];
mxid=i;
}
ret=(ret+p[i]/)%MOD;
}
//注意我们要求的不是最长回文字串而是回文串的个数,和之前的manacher有细微不同
return ret;
} void init()
{
scanf("%s",s+);
memset(ina,,sizeof(ina));
memset(inb,,sizeof(inb));
n=strlen(s+);
for (int i=;i<=n;i++)
if (s[i]=='a') ina[i]++;
else if (s[i]=='b') inb[i]++;
for (int i=;i<=n;i++) a[i]=(ina[i]),b[i]=(inb[i]);
} void solve()
{
m=n<<;
get_bit();
get_Rev();
FFT(a,);
FFT(b,);
for (int i=;i<n;i++) c[i]=a[i]*a[i]+b[i]*b[i];
FFT(c,-);
int pow[MAXN];
ll ans=;
pow[]=;
for (int i=;i<MAXN;i++) pow[i]=(pow[i-]*)%MOD;
for (int i=;i<n;i++)
{
int tmp=int(c[i].real()+0.5);
ans=(ans+(ll)pow[(tmp+)>>]-)%MOD;
}
printf("%d",(((int)ans+MOD-manacher())%MOD));
} int main()
{
init();
solve();
return ;
}

【manacher+FFT】BZOJ3160-万径人踪灭的更多相关文章

  1. 【BZOJ3160】万径人踪灭 Manacher+FFT

    [BZOJ3160]万径人踪灭 Description Input Output Sample Input Sample Output HINT 题解:自己想出来1A,先撒花~(其实FFT部分挺裸的) ...

  2. BZOJ3160 万径人踪灭(FFT+manacher)

    容易想到先统计回文串数量,这样就去掉了不连续的限制,变为统计回文序列数量. 显然以某个位置为对称轴的回文序列数量就是2其两边(包括自身)对称相等的位置数量-1.对称有啥性质?位置和相等.这不就是卷积嘛 ...

  3. BZOJ3160:万径人踪灭(FFT,Manacher)

    Solution $ans=$回文子序列$-$回文子串的数目. 后者可以用$manacher$直接求. 前者设$f[i]$表示以$i$为中心的对称的字母对数. 那么回文子序列的数量也就是$\sum_{ ...

  4. BZOJ3160 万径人踪灭 【fft + manacher】

    题解 此题略神QAQ orz po神牛 由题我们知道我们要求出: 回文子序列数 - 连续回文子串数 我们记为ans1和ans2 ans2可以用马拉车轻松解出,这里就不赘述了 问题是ans1 我们设\( ...

  5. BZOJ3160 万径人踪灭 字符串 多项式 Manachar FFT

    原文链接http://www.cnblogs.com/zhouzhendong/p/8810140.html 题目传送门 - BZOJ3160 题意 给你一个只含$a,b$的字符串,让你选择一个子序列 ...

  6. 洛谷P4199 万径人踪灭(manacher+FFT)

    传送门 题目所求为所有的不连续回文子序列个数,可以转化为回文子序列数-回文子串数 回文子串manacher跑一跑就行了,考虑怎么求回文子序列数 我们考虑,如果$S_i$是回文子序列的对称中心,那么只要 ...

  7. BZOJ3160: 万径人踪灭(FFT,回文自动机)

    BZOJ传送门: 解题思路: FFT在处理卷积时可以将自己与自己卷,在某一种字母上标1其他标0,做字符集次就好了. (回文就是直接对称可以联系偶函数定义理解,根据这个性质就可以将字符串反向实现字符串匹 ...

  8. [bzoj3160]万径人踪灭_FFT_Manacher

    万径人踪灭 bzoj-3160 题目大意:给定一个ab串.求所有的子序列满足:位置和字符都关于某条对称轴对称而且不连续. 注释:$1\le n\le 10^5$. 想法: 看了大爷的题解,OrzOrz ...

  9. BZOJ3160万径人踪灭

    Description Input & Output & Sample Input & Sample Output HINT 题解: 题意即求不连续但间隔长度对称的回文串个数. ...

  10. BZOJ3160: 万径人踪灭

    设a[i]=bool(s[i]=='a'),b[i]=bool(s[i]=='b'),考虑a和a.b和b的卷积,由于卷积是对称的,就可以统计出不连续回文子串个数了.可能说得比较简略.再用manache ...

随机推荐

  1. 快速入门react

    安装react npm install creat-react-app -g这里直接安装react的一个脚手架,里面包含了要用到的许多东西,帮助快速入门react 创建新项目 create-react ...

  2. 2017ACM暑期多校联合训练 - Team 2 1009 HDU 60563 TrickGCD (容斥公式)

    题目链接 Problem Description You are given an array A , and Zhu wants to know there are how many differe ...

  3. 游戏的物理和数学:Unity中的弹道和移动目标提前量计算

    下载地址:https://www.jianguoyun.com/p/DZPN6ocQ2siRBhihnx8 弹道计算是游戏里常见的问题,其中关于击中移动目标的自动计算提前量的话题,看似简单,其实还是挺 ...

  4. React Native 与 夜神模拟器的绑定

    之前一直用真机去调试, 每回更新一次都需要手动摇晃手机后才能reload JS, OMG,太麻烦了. 后来寻思模拟器网上推荐用Geny...什么的模拟器,但是那个模拟器还需要VBox一起用. 有点麻烦 ...

  5. struts的标签

    <%@ taglib uri="/struts-tags" prefix="s"%> <%@ taglib uri="/WEB-IN ...

  6. linux 查看内存和cpu占用比较多的进程

    1.可以使用一下命令查使用内存最多的10个进程        ps -aux | sort -k4nr | head -n 102. 可以使用一下命令查使用CPU最多的10个进程        ps ...

  7. URAL题解二

    URAL题解二 URAL 1082 题目描述:输出程序的输入数据,使得程序输出"Beutiful Vasilisa" solution 一开始只看程序的核心部分,发现是求快排的比较 ...

  8. 第一天开始使用Oracle

    上半年虽然已经学习了Oracle,但是基本上实验课都没怎么实践过,感觉自己之前过得太水了! 在我的印象里,Oracle 的难度相当于工程师的建设一个亚洲最大的医院一样,也如医生的99%失败率的手术: ...

  9. Maven整合Spring与Solr

    首先,在maven的pom.xml文件中配置对spring和solrj客户端的依赖: <project xmlns="http://maven.apache.org/POM/4.0.0 ...

  10. **[权限控制] 利用CI钩子实现权限认证

    http://codeigniter.org.cn/forums/thread-10877-1-1.html 一直没找到CI的权限认证扩展,以前好像找到过一个老外的扩展,不过不怎么好用,现在记不清了, ...