题面

Bzoj

Sol

求不连续回文子序列的个数

\(ans=\)回文子序列个数-连续回文子序列个数

即回文子序列个数-回文子串个数

后面直接\(Manacher\)就好了

考虑前面的

枚举对称轴,设\(f[i]\)表示对称轴\(i\)两边相同字符的对数

那么最终答案就是\(\sum 2^{f[i]}-1\)

考虑求\(f[i]\)

只有当原串中的两个字符相同才会有贡献

也就是\(s[i-x]=s[i+x]\)

单独考虑\(a\)和\(b\)的贡献

\(f[i]=\sum [s[i-x]==s[i+x]]\)

设当前考虑\(a\)的贡献

把是\(a\)的设为\(1\)不是的为\(0\),做个卷积就可以求出\(f\)

那么就可以\(FFT\)辣

注意两个字符之间也算对称轴

# include <bits/stdc++.h>
# define RG register
# define IL inline
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;
const int Zsy(1e9 + 7);
const int _(5e5 + 5);
const double PI(acos(-1)); int n, p[_];
ll f[_];
int N, M, l, r[_];
char s[_], a[_];
struct Complex{
double real, image;
IL Complex(){
real = image = 0;
} IL Complex(RG double a, RG double b){
real = a, image = b;
} IL Complex operator +(RG Complex B){
return Complex(real + B.real, image + B.image);
} IL Complex operator -(RG Complex B){
return Complex(real - B.real, image - B.image);
} IL Complex operator *(RG Complex B){
return Complex(real * B.real - image * B.image, real * B.image + image * B.real);
}
} A[_], B[_]; IL void FFT(RG Complex *P, RG int opt){
for(RG int i = 0; i < N; ++i) if(i < r[i]) swap(P[i], P[r[i]]);
for(RG int i = 1; i < N; i <<= 1){
RG Complex W(cos(PI / i), opt * sin(PI / i));
for(RG int j = 0, p = i << 1; j < N; j += p){
RG Complex w(1, 0);
for(RG int k = 0; k < i; ++k, w = w * W){
RG Complex X = P[k + j], Y = w * P[k + j + i];
P[k + j] = X + Y, P[k + j + i] = X - Y;
}
}
}
} IL void Mul(){
FFT(A, 1);
for(RG int i = 0; i < N; ++i) B[i] = A[i] * A[i];
FFT(B, -1);
for(RG int i = 0; i < N; ++i) B[i].real = B[i].real / N + 0.5;
for(RG int i = 1; i <= M; ++i) f[i] += ((ll)(B[i].real) + 1) >> 1;
} IL ll Manacher(){
RG ll ans = 0; RG int mx = 0, len = 1; a[1] = '#';
for(RG int i = 1; i <= n; ++i) a[++len] = s[i], a[++len] = '#';
for(RG int i = 1, id = 0, mx = 0; i <= len; ++i){
if(i < mx) p[i] = min(mx - i, p[(id << 1) - i]);
while(i - p[i] && i + p[i] <= len && a[i - p[i]] == a[i + p[i]]) ++p[i];
if(p[i] + i > mx) mx = p[i] + i, id = i;
(ans += p[i] >> 1) %= Zsy;
}
return ans;
} IL ll Pow(RG ll x, RG ll y){
RG ll ret = 1;
for(; y; y >>= 1, x = x * x % Zsy)
if(y & 1) ret = ret * x % Zsy;
return ret;
} int main(RG int argc, RG char* argv[]){
scanf(" %s", s + 1); n = strlen(s + 1);
for(M = n + n, N = 1; N <= M; N <<= 1) ++l;
for(RG int i = 0; i < N; ++i) r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1));
RG ll ans = -Manacher();
for(RG int i = 0; i < N; ++i) A[i] = Complex(s[i] == 'a', 0);
Mul();
for(RG int i = 0; i < N; ++i) A[i] = Complex(s[i] == 'b', 0);
Mul();
for(RG int i = 1; i <= M; ++i) (ans += Pow(2, f[i]) - 1) % Zsy;
printf("%lld\n", (ans + Zsy) % Zsy);
return 0;
}

Bzoj3160:万径人踪灭的更多相关文章

  1. [bzoj3160]万径人踪灭_FFT_Manacher

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

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

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

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

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

  4. BZOJ3160万径人踪灭

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

  5. BZOJ3160: 万径人踪灭

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

  6. bzoj千题计划302:bzoj3160: 万径人踪灭

    https://www.lydsy.com/JudgeOnline/problem.php?id=3160 不连续的回文串数量=所有的回文序列数量-连续的回文子串 连续的回文子串: manacher ...

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

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

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

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

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

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

  10. 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/常用套路【入门】

    原文链接https://www.cnblogs.com/zhouzhendong/p/Fast-Fourier-Transform.html 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/ ...

随机推荐

  1. nodejs express搭建一个网站整理

    先前用安卓完成了一个优惠券搜索的app,发现在app上操作比较麻烦,于是决定弄个网页版的.做网站是自己的擅长的,毕竟毕业之后咱一直用asp.net mvc做网站也好几个年头了. 可是这次我又想换个方式 ...

  2. 让我们一起摇摆 Turnipbit体感遥控车

    相信大家对Microbit是非常熟悉的,而今天我们做的这个小玩具所用的核心板是Turnipbit,是基于 Microbit开发的一块适合儿童适用的板卡.基本使用原理是一样的,这里就不多介绍了,代码这方 ...

  3. Windows使用问题总结

    1 电脑休眠恢复之后无法识别Wifi无线网络 首先,重启电脑:其次,打开网络和共享中心,点击更改适配器设置:最后,在对应的无线网络连接图标上点击鼠标右键,属性,配置,电源选项,允许计算机关闭此设备以节 ...

  4. CentOS6搭建OpenVPN服务器

    一.服务器端安装及配置 服务器环境:干净的CentOS6.3 64位系统 内网IP:10.143.80.116 外网IP:203.195.xxx.xxx OpenVPN版本:OpenVPN 2.3.2 ...

  5. 请小心使用 ng-repeat 中的 $index

    自己自学的时候,遇到$index不知道它是如何使用的,所以上网搜了一下,发现了这个关于使用$index可能会出现的一个小BUG,和大家分享一下 PS:我是小白,欢迎指正,非常感谢! 以下是全文: &q ...

  6. vuejs、eggjs全栈式开发设备管理系统

    vuejs.eggjs全栈式开发简单设备管理系统 业余时间用eggjs.vuejs开发了一个设备管理系统,通过mqtt协议上传设备数据至web端实时展现,包含设备参数分析.发送设备报警等模块.收获还是 ...

  7. Sqlserver将数据从一张表插入到另一张表

    1.如果是整个表复制表达如下: insert into table1 select * from table2 2.如果是有选择性的复制数据表达如下: insert into table1(colum ...

  8. C#委托与事件--简单笔记

    委托 简单记录点东西 适合似懂非懂的朋友看看 委托类型用来定义和响应应用程序中的回调. 借此可以设计各种有面向对象特性的代码模式.下面要说的事件在我看来就是委托的一种实现,再深一步讲,利用委托加事件, ...

  9. Ubuntu下Maven配置与Maven项目创建教程

    一. Ubuntu下Maven配置 windows下Maven配置参考http://www.cnblogs.com/LexMoon/p/JavaMaven.html ubuntu下Maven地址htt ...

  10. 最短路径问题(Floyd-Warshall模板)

    #include<bits/stdc++.h> using namespace std; int n; int x,y; ][]; ][]; int m,s,t; int main() { ...