首先正难则反,想到答案即为满足第一条要求的回文子序列数量,减去回文子串数量。回文子串数量 \(hash+\) 二分即可,考虑前半部分。

假如我们将一个回文子序列一层层剥开,就会发现它其实是由多个相同的字母对拼成的。那么容易想到把字母 \(a\) 和字母 \(b\) 的贡献分开计算。那第一条要求就可以转化为所有字母对中心相同,用 \(FFT\) 计算 \(c_k\),表示所有 \(i+j=k\) 的字母对数量即可。

时间复杂度 \(O(n\log n)\)。

#include<bits/stdc++.h>
#define int long long
#define ull unsigned int
using namespace std;
const ull q=1145141;
const int N=4e5+5,p=1e9+7;
const double pi=acos(-1);
namespace FFT{
int rev[N],mx,k;
struct comn{double a,b;};
struct dft{comn fg[N];};
comn operator+(comn &x,comn &y){
return {x.a+y.a,x.b+y.b};
}comn operator-(comn &x,comn &y){
return {x.a-y.a,x.b-y.b};
}comn operator*(comn &x,comn &y){
return {x.a*y.a-x.b*y.b,x.a*y.b+x.b*y.a};
}void operator+=(comn &x,comn &y){x=x+y;}
void operator-=(comn &x,comn &y){x=x-y;}
void operator*=(comn &x,comn &y){x=x*y;}
void operator+=(dft &x,dft &y){
for(int i=0;i<mx;i++) x.fg[i]+=y.fg[i];
}void operator-=(dft &x,dft &y){
for(int i=0;i<mx;i++) x.fg[i]-=y.fg[i];
}void init(int n){
mx=1,k=0,rev[0]=0;
while(mx<=n) mx*=2,k++;
for(int i=0;i<mx;i++)
rev[i]=(rev[i>>1]>>1)|((i&1)<<(k-1));
}void fft(dft &a,int fl){
for(int i=0;i<mx;i++)
if(i<rev[i]) swap(a.fg[i],a.fg[rev[i]]);
comn o={cos(pi),fl*sin(pi)},w={1,0};
for(int i=1;i<mx;i*=2,o={cos(pi/i),fl*sin(pi/i)})
for(int j=0;j<mx;j+=i*2,w={1,0})
for(int l=j;l<j+i;l++){
comn x=a.fg[l],y=w*a.fg[l+i];
a.fg[l]+=y,a.fg[l+i]=x-y,w*=o;
}
}
}using namespace FFT;
int n,ans;string s;dft t[2];
ull hsh1[N],hsh2[N],qp[N];
int qpow(int x,int y){
int re=1;
while(y){
if(y&1) re=re*x%p;
x=x*x%p,y>>=1;
}return re;
}ull hs1(int l,int r){
return hsh1[l]-hsh1[r]*qp[l-r];
}ull hs2(int l,int r){
return hsh2[l]-hsh2[r]*qp[r-l];
}signed main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>s,n=s.size(),qp[0]=1;
s=" "+s,init(2*n);
for(int i=1;i<=n;i++){
t[s[i]-'a'].fg[i].a++,qp[i]=qp[i-1]*q;
hsh1[i]=hsh1[i-1]*q+s[i]-'a';
}for(int i=n;i;i--)
hsh2[i]=hsh2[i+1]*q+s[i]-'a';
fft(t[0],1),fft(t[1],1);
for(int i=0;i<mx;i++){
t[0].fg[i]*=t[0].fg[i];
t[1].fg[i]*=t[1].fg[i];
}fft(t[0],-1),fft(t[1],-1);
for(int i=2;i<=2*n;i++){
int sum=((t[0].fg[i].a+t[1].fg[i].a)/mx+0.5);
ans+=qpow(2,sum/2-(i&1)+1)-1;
}for(int i=1;i<=n;i++){
int l=1,sum=0;
int r=min(i,n-i+1);
while(l<=r){
int mid=(l+r)/2;
if(hs1(i,i-mid)==hs2(i,i+mid))
l=mid+1,sum=mid;else r=mid-1;
}ans-=sum;
}for(int i=1;i<n;i++){
int l=1,sum=0;
int r=min(i,n-i);
while(l<=r){
int mid=(l+r)/2;
if(hs1(i,i-mid)==hs2(i+1,i+mid+1))
l=mid+1,sum=mid;else r=mid-1;
}ans-=sum;
}cout<<(ans%p+p)%p;
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万径人踪灭

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

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

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

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

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

  6. BZOJ3160: 万径人踪灭

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

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

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

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

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

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

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

  10. $FFT/NTT/FWT$题单&简要题解

    打算写一个多项式总结. 虽然自己菜得太真实了. 好像四级标题太小了,下次写博客的时候再考虑一下. 模板 \(FFT\)模板 #include <iostream> #include < ...

随机推荐

  1. elastic8.4.0搜索+logstash<=>mysql实时同步+kibana可视化操作+netcore代码笔记

    做全文搜索,es比较好用,安装可能有点费时费力.mysql安装就不说了.主要是elastic8.4.0+kibana8.4.0+logstash-8.16.1,可视化操作及少了netcore查询代码. ...

  2. uniapp云数据库笔记

    1.基本概念 云数据库:一个云空间只能有一个数据库,一个数据库可以有多个集合(表),每个表可以有多行数据(文档) DB Schema:是基于 JSON 格式定义的数据结构的规范,每个表有多少字段都需要 ...

  3. web移动端屏幕适配方案

    因为手机屏幕的分辨率大小不一 ,如果使用传统的静态布局,把每个元素的宽高样式写死,在不同的屏幕中就有各种各样的显示效果.这显然不是我们想要的结果.我们需要的是根据屏幕分辨率的不同,来适配不同的样式大小 ...

  4. 记一次vsix安装异常

    vsix是vs扩展安装的包,里面包含了vs扩展功能的相关内容和元数据. 由于个人需求,我通过zip工具,对其中的许可文件进行了更新,将EULA.rtf替换为eula.txt.但在安装过程中报错,日志提 ...

  5. electron项目build报资源包下载出错

    前情 公司有个桌面端项目是基于Electron开发的. 坑 上一次遇到npm install时安装electron无法安装,通过配置.npmrc文件解决了,今天在在执行npm run build的时候 ...

  6. 高中生入门学习c/c++指导

    一.c与c++关系 参考图示: 可见,c与c++的基本部分是相同的,会有一些小区别,不妨一起学.DEV-C++能支持C++和C语言编程 二.学习资料网站介绍 1.C语言初阶--手把手教零基础/新手入门 ...

  7. Elm 和 Jetpack Compose 殊途同归及 MVVM 缺点分析

    Html.lazy · An Introduction to Elm 可能搞 vdom 的都会到 lazy renderer 这一步,react 可能也可以这么搞或者已经这么搞了我不知道,Elm 提到 ...

  8. 【NAS】绿联NAS UGOS PRO 使用natfrp(Sakura Frp)内网穿透访问Docker应用

    配置加速 https://registry.cn-hongkong.aliyuncs.com 下载镜像 创建容器 [容器]-[创建]-[手动创建]- 选择你下载的镜像即可 在日志中查看密码 访问容器 ...

  9. 开源产品测评之 SQL 上线能力

    背景 近期,我司准备引入一款 SQL 审核产品来供内部流程使用,解决目前 SQL 人工上线的流程管控问题,目标是对业内的开源产品进行调研,选型一款作为落地方案,后期如果内部有需求可能会进行二次开发.我 ...

  10. 搭建SpringBoot中验证数据机制问题 Add a provider like Hibernate Validator (RI) to your classpath

    搭建SpringBoot中的验证数据机制时出现的错误 报错代码 java.lang.IllegalStateException: Failed to load ApplicationContext a ...