【题目大意】

在一个仅仅含有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. Django中的MiddleWare中间件

    1. middleware简介 Django的middleware的概念相当于SSH框架里面的filter的概念.中间键的作用就是对所有的request,在request前,和在response后做一 ...

  2. laravel学习教程整理

    百度传课:https://chuanke.baidu.com/v5847462-219167-1421398.html

  3. 在Oracle中查询表的大小

    SELECT segment_name AS TABLENAME,round(BYTES/1024/1024,2)  FROM user_segments WHERE segment_name='表名 ...

  4. java正则: 忽略大小写匹配

    import java.util.regex.Matcher; import java.util.regex.Pattern; import com.sun.org.apache.xerces.int ...

  5. 014 JVM面试题

    转自:http://www.importnew.com/31126.html 本文从 JVM 结构入手,介绍了 Java 内存管理.对象创建.常量池等基础知识,对面试中 JVM 相关的基础题目进行了讲 ...

  6. Maven如何发布项目到一个Tomcat中

    首先,在本地tomcat的conf/tomcat-users.xml 中配置一个user,准备让maven接入时使用: <role rolename="admin-gui"/ ...

  7. Builder设计模式--改善构造器多个参数时可显著改善可读性

    作为一名程序开发者,设计模式其实一直有在接触,只是没有专门的去学过,所以可能对设计模式没有一个系统的理解.在一次项目中,需要使用到第三方服务商提供的功能,为了尽快的熟悉其功能代码,在官网下了demo来 ...

  8. plsql实例精讲部分笔记

    转换sql: create or replace view v_sale(year,month1,month2,month3,month4,month5,month6,month7,month8,mo ...

  9. 查找网页元素对应的js代码

    按F12打开调试窗口,切换到Sources选项卡,最右边的Event Listener Breakpoints里勾选Mouse下的mouseover即可,当鼠标移动到图片上时触发mouseover事件 ...

  10. Kail Linux渗透测试之测试工具Armitage

    Kali Linux下的Armitage是一个很强大的渗透工具,图形化操作页面,但我们把kali linux装在虚拟机里面,然后再启动armitage就会出现一个error,他会给你一个message ...