【BZOJ3160】万径人踪灭

Description

Input

Output

Sample Input

Sample Output

HINT

题解:自己想出来1A,先撒花~(其实FFT部分挺裸的)

做这道题,第一思路很重要,显然看到这题的第一想法就是ans=总数-不合法(不要问我为什么显然)。因为向这种用补集法的题一般都会给一些很奇葩的限制条件,但是一旦换个角度去想就很水了,好了不多说废话了。

显然,不合法的情况,也就是连续的回文区间的方案数,我们直接上Manacher就搞定了嘛!答案就是所有对称轴的(最长回文串长度+1)/2之和(是的,很显然)

对于不合法的情况,我们发现两串对称的情况跟卷积的形式类似(FFT做多了吧?),但是问题来了,怎么构造出一个卷积,使得它的值就是回文子串的个数呢?

我们发现原串只有a或b,所以思考能不能构造出一种卷积,使得对应位置的值跟下面一样

a*b->0       b*a->0        a*a->1     b*b->1

如果把a看成0,b看成1,这显然是一个异或,然而并没什么卵用。但我们如果把a看成0,b看成1,可以满足只有b*b是1,其他都是0;同理,把a看成1,b看成0,可以满足只有a*a是1,其他都是0,然后我们对这两种情况分别求一次卷积,就能得到:以i为对称中心的最长子序列的回文半径长度。这里注意一下,用于是两个一样的多项式相乘,所以每对字符会被算成两次(单个字符自我对称的除外),所以我们要的回文半径应该是(x+1)/2

然而半径长度并不是方案数,由于每对对称的字符都可以选或不选,所以对答案的贡献就是2^长度-1(因为你不能一个也不选吧?)

好吧,感觉说了这么多又有点说不明白了,所以欢迎提问和hack~

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#define pi acos(-1.0)
#define mod 1000000007
using namespace std;
int n,ans;
struct cp
{
double x,y;
cp (double a,double b){x=a,y=b;}
cp (){}
cp operator + (cp a){return cp(x+a.x,y+a.y);}
cp operator - (cp a){return cp(x-a.x,y-a.y);}
cp operator * (cp a){return cp(x*a.x-y*a.y,x*a.y+y*a.x);}
}n1[1<<20],n2[1<<20];
int s[1<<20],ret[1<<20],rl[1<<20],pn[1<<20];
char str[1<<20];
void FFT(cp *a,int len,int f)
{
int i,j,k,h;
cp t;
for(i=k=0;i<len;i++)
{
if(i>k) swap(a[i],a[k]);
for(j=(len>>1);(k^=j)<j;j>>=1);
}
for(h=2;h<=len;h<<=1)
{
cp wn(cos(f*2*pi/h),sin(f*2*pi/h));
for(j=0;j<len;j+=h)
{
cp w(1.0,0);
for(k=j;k<j+h/2;k++) t=w*a[k+h/2],a[k+h/2]=a[k]-t,a[k]=a[k]+t,w=w*wn;
}
}
}
void work(cp *a,cp *b,int len)
{
FFT(a,len,1),FFT(b,len,1);
for(int i=0;i<len;i++) a[i]=a[i]*b[i];
FFT(a,len,-1);
for(int i=0;i<len;i++) ret[i]+=(int)(a[i].x/len+0.1);
}
int main()
{
scanf("%s",str);
int i,mx,pos,len=strlen(str);
for(i=0;i<len;i++) s[n++]=0,s[n++]=str[i]-'a';
s[n++]=0;
for(mx=-1,i=0;i<n;i++)
{
if(mx>i) rl[i]=min(mx-i+1,rl[2*pos-i]);
else rl[i]=1;
for(;i+rl[i]<n&&rl[i]<=i&&s[i+rl[i]]==s[i-rl[i]];rl[i]++);
if(mx<i+rl[i]-1) mx=i+rl[i]-1,pos=i;
}
for(i=0;i<n;i++) ans=(ans-rl[i]/2+mod)%mod;
for(len=1;len<2*n;len<<=1);
for(i=0;i<len;i++) n1[i]=n2[i]=cp(0,0);
for(i=1;i<n;i+=2) n1[i]=n2[i]=cp(s[i],0);
work(n1,n2,len);
for(i=0;i<len;i++) n1[i]=n2[i]=cp(0,0);
for(i=1;i<n;i+=2) n1[i]=n2[i]=cp(s[i]^1,0);
work(n1,n2,len);
for(pn[0]=i=1;i<=n;i++) pn[i]=(pn[i-1]<<1)%mod;
for(i=0;i<n;i++) ans=(ans+pn[(ret[i<<1]+(i&1))>>1]-1)%mod;
printf("%d",ans);
return 0;
}

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

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

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

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

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

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

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

  4. 【BZOJ3160】万径人踪灭(FFT,Manacher)

    [BZOJ3160]万径人踪灭(FFT,Manacher) 题面 BZOJ 题解 很容易想到就是满足条件的子序列个数减去回文子串的个数吧... 至于满足条件的子序列 我们可以依次枚举对称轴 如果知道关 ...

  5. 【BZOJ3160】 万径人踪灭(FFT,manacher)

    前言 多项式真的很难♂啊qwq Solution 考虑求的是一个有间隔的回文串,相当于是: 总的答案-没有间隔的答案 考虑总的答案怎么计算?FFT卷一下就好了. 对于每一位字符,有两种取值,然后随便卷 ...

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

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

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

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

  8. 万径人踪灭(FFT+manacher)

    传送门 这题--我觉得像我这样的菜鸡选手难以想出来-- 题目要求求出一些子序列,使得其关于某个位置是对称的,而且不能是连续一段,求这样的子序列的个数.这个直接求很困难,但是我们可以先求出所有关于某个位 ...

  9. bzoj 3160: 万径人踪灭【FFT+manacher】

    考虑正难则反,我们计算所有对称子序列个数,再减去连续的 这里减去连续的很简单,manacher即可 然后考虑总的,注意到关于一个中心对称的两点下标和相同(这样也能包含以空位为对称中心的方案),所以设f ...

随机推荐

  1. Jboss as 服务器基本设置

    http://www.cnblogs.com/lovingprince/archive/2009/09/03/2166307.html Step one: download JBoss Applica ...

  2. 【转】GGTalk即时通讯系统(支持广域网)终于有移动端了!(技术原理、实现、源码)

    原文地址:http://www.cnblogs.com/justnow/p/4836636.html 首先要感谢大家一直以来对于GGTalk即时通讯系统的关注和支持!GGTalk即时通讯系统的不断完善 ...

  3. [emqttd] (EMQ)

    [emqttd] (EMQ)是采用Erlang语言开发,全面支持MQTT V3.1.1协议,支持集群和大规模连接的开源MQTT消息服务器. [emqttd]致力于发布一个基于Erlang/OTP语言平 ...

  4. convertView与ViewHolder有什么区别,好处在哪里

        convertView 在API中的解释是The old view to reuse, if possible, 第一次getView时还没有convertView,这时你便创建了一个新的vi ...

  5. ConcurrentBag同线程元素的添加和删除

    https://www.mgenware.com/blog/?p=232 ConcurrentBag<T>对于同一个线程值的添加和删除是非常快的,因为ConcurrentBag内部将数据按 ...

  6. mysql-group-replication 测试环境的搭建与排错

    mysql-group-replication 是由mysql-5.7.17这个版本提供的强一致的高可用集群解决方案 1.环境规划 主机ip 主机名 172.16.192.201 balm001 17 ...

  7. unity, unity中GL.MultMatrix的一个超级bug

    GL.MultMatrix与OpenGL固定管线的glMultMatrix函数行为并不一致,不是累乘,而是覆盖. 例如下面例子,本来预期是在(100,100)处画一个方块,而实际效果却是在(0,0)处 ...

  8. erlang supervisor中启动普通的进程

    文字部分转自: http://1234n.com/?post/qou3eb supervisor的子进程 一开始使用supervisor的时候,我用的是init/1返回子进程规格列表的方式,并且所有子 ...

  9. 使用7za压缩zip包的命令,当中屏蔽部分文件夹内容

    7za.exe a -r  "D:\paages\prduct\produtConfig.zip" "E:/tm\packaes\poduct" -xr!doc ...

  10. 操作XmlDocument时,出现"System.OutOfMemoryException"异常,如何解决加载大数据的情况?

    System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.at System.St ...