【manacher+FFT】BZOJ3160-万径人踪灭
【题目大意】
在一个仅仅含有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-万径人踪灭的更多相关文章
- 【BZOJ3160】万径人踪灭 Manacher+FFT
[BZOJ3160]万径人踪灭 Description Input Output Sample Input Sample Output HINT 题解:自己想出来1A,先撒花~(其实FFT部分挺裸的) ...
- BZOJ3160 万径人踪灭(FFT+manacher)
容易想到先统计回文串数量,这样就去掉了不连续的限制,变为统计回文序列数量. 显然以某个位置为对称轴的回文序列数量就是2其两边(包括自身)对称相等的位置数量-1.对称有啥性质?位置和相等.这不就是卷积嘛 ...
- BZOJ3160:万径人踪灭(FFT,Manacher)
Solution $ans=$回文子序列$-$回文子串的数目. 后者可以用$manacher$直接求. 前者设$f[i]$表示以$i$为中心的对称的字母对数. 那么回文子序列的数量也就是$\sum_{ ...
- BZOJ3160 万径人踪灭 【fft + manacher】
题解 此题略神QAQ orz po神牛 由题我们知道我们要求出: 回文子序列数 - 连续回文子串数 我们记为ans1和ans2 ans2可以用马拉车轻松解出,这里就不赘述了 问题是ans1 我们设\( ...
- BZOJ3160 万径人踪灭 字符串 多项式 Manachar FFT
原文链接http://www.cnblogs.com/zhouzhendong/p/8810140.html 题目传送门 - BZOJ3160 题意 给你一个只含$a,b$的字符串,让你选择一个子序列 ...
- 洛谷P4199 万径人踪灭(manacher+FFT)
传送门 题目所求为所有的不连续回文子序列个数,可以转化为回文子序列数-回文子串数 回文子串manacher跑一跑就行了,考虑怎么求回文子序列数 我们考虑,如果$S_i$是回文子序列的对称中心,那么只要 ...
- BZOJ3160: 万径人踪灭(FFT,回文自动机)
BZOJ传送门: 解题思路: FFT在处理卷积时可以将自己与自己卷,在某一种字母上标1其他标0,做字符集次就好了. (回文就是直接对称可以联系偶函数定义理解,根据这个性质就可以将字符串反向实现字符串匹 ...
- [bzoj3160]万径人踪灭_FFT_Manacher
万径人踪灭 bzoj-3160 题目大意:给定一个ab串.求所有的子序列满足:位置和字符都关于某条对称轴对称而且不连续. 注释:$1\le n\le 10^5$. 想法: 看了大爷的题解,OrzOrz ...
- BZOJ3160万径人踪灭
Description Input & Output & Sample Input & Sample Output HINT 题解: 题意即求不连续但间隔长度对称的回文串个数. ...
- BZOJ3160: 万径人踪灭
设a[i]=bool(s[i]=='a'),b[i]=bool(s[i]=='b'),考虑a和a.b和b的卷积,由于卷积是对称的,就可以统计出不连续回文子串个数了.可能说得比较简略.再用manache ...
随机推荐
- 原创:HTML 头像截取上传 JS+PHP 整合包~
关于: 关于头像上传这个东西,网上一搜乱七八糟的一堆然而很少很少有自己中意的插件一怒之下就自己写一个... 用法: <!DOCTYPE html> <html lang=" ...
- spring mvc convention over configuration 之 RequestToViewNameTranslator
1. RequestToViewNameTranslator简介 在springmvc中很多地方都是约定优于配置的,比如这种写法: @Controller public class IndexActi ...
- Vmware安装ubuntu详细教程
1.环境准备: (1) 范例系统为WIN10 64位家庭普通版,已正确安装虚拟机VMware Workstation 12 Pro.(2) 下载Ubuntu系统. 2.安装过程: 2.1 VMware ...
- html中去掉文本框(input type="text")的边框或只显示下边框
去掉: <input type="text" name="textfield" style="border:0px;"&g ...
- 定位、判断、cookie的脚本案例
Action(){ lr_think_time(20); lr_start_transaction("µã»÷ÊÂÏî°ìÀíÇé¿ö°´Å¥"); web_url("L ...
- python安装模块的时候报错error: command 'gcc' failed with exit status 1
[情况] 在写Python代码的时候,需要用到psutil模块,需要安装. 但是在安装时,报错:error: command 'gcc' failed with exit status 1 [解决步骤 ...
- GPS位置模拟-安卓
测试定位功能时都需要位置模拟,一般有如下3种方式: a)手机上安装第三方模拟软件:需要Root: b)PC模拟其中运行app并模拟位置:不能在真机上运行,手机兼容性不能测试到: b)在app中让开发增 ...
- C语言再学习之 setjmp与longjmp
前不久在阅读Quake3源代码的时候,看到一个陌生的函数:setjmp,一番google和查询后,觉得有必要针对setjmp和longjmp这对函数写一篇blog,总结一下. setjmp和longj ...
- BeanUtils简化数据封装
BeanUtils主要用来封装JavaBean的. 1.什么是JavaBean JavaBean指的是标准的类. 要求: 1. 类必须被public修饰2. 必须提供空参的构造器3. 成员变量必须使用 ...
- Codeforces 799B - T-shirt buying(STL)
题目链接:http://codeforces.com/problemset/problem/799/B 题目大意:有n件T恤,每件T体恤都分别有价格(每件衣服的价格不重复).前面的颜色.背部的颜色三种 ...