题面

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. Ubuntu配置Nginx虚拟主机和支持ThinkPHP

    [Nginx配置虚拟主机] 每一个 server { listen       80;         server_name  www.a.com; ..... } 就表示一台虚拟域名, 然后对应的 ...

  2. 聊聊Vue.js的template编译

    写在前面 因为对Vue.js很感兴趣,而且平时工作的技术栈也是Vue.js,这几个月花了些时间研究学习了一下Vue.js源码,并做了总结与输出. 文章的原地址:https://github.com/a ...

  3. ABP框架源码学习之授权逻辑

    asp.net core的默认的几种授权方法参考"雨夜朦胧"的系列博客,这里要强调的是asp.net core mvc中的授权和asp.net mvc中的授权不一样,建议先看前面& ...

  4. 微信小程序下拉框

    微信小程序里没有和HTML里的下拉框一样的组件,想要相同的效果只能自己写一个,先看效果 下面来看一下代码: 首先WXML <view class='select_box'> <vie ...

  5. 剑指offer面试题-Java版-持续更新

    最近在用Java刷剑指offer(第二版)的面试题.书中原题的代码采用C++编写,有些题的初衷是为了考察C++的指针.模板等特性,这些题使用Java编写有些不合适.但多数题还是考察通用的算法.数据结构 ...

  6. uva225 回溯剪枝

    这道题要剪枝,不然会超时,还有就是每次参加过的城市下次不能再参观,不然会WA. 对于障碍物的坐标我用了两种方法,第一种就是直接用STL里面的set,对于判断是否访问过直接用的count,用时960ms ...

  7. Redux:从action到saga

    前端应用消失的部分 一个现代的.使用了redux的前端应用架构可以这样描述: 一个存储了应用不可变状态(state)的store 状态(state)可以被绘制在组件里(html或者其他的东西).这个绘 ...

  8. Luogu P1877 [HAOI2012]音量调节

    题目描述 一个吉他手准备参加一场演出.他不喜欢在演出时始终使用同一个音量,所以他决定每一首歌之前他都需要改变一次音量.在演出开始之前,他已经做好一个列表,里面写着每首歌开始之前他想要改变的音量是多少. ...

  9. 安装VMware Workstation提示the msi failed的解决办法

    有朋友安装VMware Workstation时出现报错,提示the msi failed等信息,原来他以前安装过绿色版.优化版的VM,但删掉后重装VM就会有这样的报错提示,如果你也遇到了相同的困扰, ...

  10. HashMap/HashSet,hashCode,哈希表

    hash code.equals和“==”三者的关系 1) 对象相等则hashCode一定相等: 2) hashCode相等对象未必相等. == 是比较地址是否相等,JAVA中声明变量都是引用嘛,不同 ...