【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 ...
随机推荐
- Verilog笔记.5.同步、异步
在数字电路中经常有同步synchronism.异步asynchronism的概念.异步指输入信号和时钟无关:同步指输入信号和时钟信号有关,实际上就是输入信号和时钟信号进行了与运算或者与非运算.实际开发 ...
- Distance Gym - 102028I (思维)
题目链接:https://cn.vjudge.net/problem/Gym-102028I 具体思路:首先我们选定左边界和右边界.然后每一次按照左边一个,第二次右边一个的规律往上就可以了 具体原因: ...
- Attention-over-Attention Neural Networks for Reading Comprehension论文总结
Attention-over-Attention Neural Networks for Reading Comprehension 论文地址:https://arxiv.org/pdf/1607.0 ...
- localStorage H5本地存储
域内安全.永久保存.即客户端或浏览器中来自同一域名的所有页面都可访问localStorage数据且数据除了删除否则永久保存,但客户端或浏览器之间的数据相互独立. <!doctype html&g ...
- skb_reserve(skb,2)中的2的意义
skb_reserve() skb_reserve()在数据缓存区头部预留一定的空间,通常被用来在数据缓存区中插入协议首部或者在某个边界上对齐.它并没有把数据移出或移入数据缓存区,而只是简单地更新了数 ...
- python之pandas&&DataFrame(二)
简单操作 Python-层次聚类-Hierarchical clustering >>> data = pd.Series(np.random.randn(10),index=[[' ...
- 实习day2:@2X图片,git,coding.net,
@2X是5和6系列的图片,@3X是6P等大屏的图片 本公司目前只用@2X的图片适配. 比如20X27的图片 1x, 就是原始大小: 用2X, 就除以2,变成10X13.5: 如果用3X的, 就除以3, ...
- Zabbix定义报警机制
1. 修改zabbix配置文件 #取消注释或添加一行 cat -n /etc/zabbix/zabbix_server.conf |grep --color=auto "AlertScrip ...
- 洛谷P1789【Mc生存】插火把 题解
题目传送门 这道题目可以纯暴力: #include<bits/stdc++.h> //Minecraft 666 using namespace std; ][]; int n,m,k,a ...
- JS模块化规范CMD之SeaJS
1. 在接触规范之前,我们用模块化来封装代码大多为如下: ;(function (形参模块名, 依赖项, 依赖项) { // 通过 形参模块名 修改模块 window.模块名 = 形参模块名 })(w ...