P4199

题目描述

题解

首先问题可以转化为”以某一位置对称的回文子序列数-回文子串数“
回文子串数很好解决,manacher\字符串哈希都可解决

考虑前半部分如何解决?

由于只有a,ba,ba,b两个字符。
考虑用A(x),B(x)A(x),B(x)A(x),B(x)来表示字符串中的′a′,′b′'a','b'′a′,′b′,即令A(x)A(x)A(x)中′a′'a'′a′的位置前系数为111,其余为000,B(x)B(x)B(x)反过来。
于是A(x)A(x)A(x)自乘,那么xix^ixi项前的系数即代表以i2\frac{i}{2}2i​位置为对称轴的对称字符对数的222倍(重复加了),B(x)B(x)B(x)同理。两者系数相加,即为总的对称字符对数。

设xix^ixi项前的系数为ccc,如果iii处为字符,那么方案数即是2c+1−1(加上中间位置的字符)2^{c+1}-1(加上中间位置的字符)2c+1−1(加上中间位置的字符),否则即为2c−12^c-12c−1
那么问题就完全解决了。

代码

#include<bits/stdc++.h>
#define ll long long
#define LL unsigned long long
#define M 2000009
using namespace std;
int read(){int f=1,re=0;char ch;for(ch=getchar();!isdigit(ch)&&ch!='-';ch=getchar());if(ch=='-'){f=-1,ch=getchar();}for(;isdigit(ch);ch=getchar()) re=(re<<3)+(re<<1)+ch-'0';return re*f;
}
const int g=3;
const int mod=998244353;
const int p=1e9+7;
int r[M];int ksm(int a,int b,int MOD){int ans=1;while(b){if(b&1) ans=(ll)ans*a%MOD;a=(ll)a*a%MOD;b>>=1;}return ans%MOD;
}
void ntt(int *A,int lim,int type){for(int i=0;i<lim;i++) if(i<r[i]) swap(A[i],A[r[i]]);for(int mid=1;mid<lim;mid<<=1){int W=ksm(g,(mod-1)/(mid<<1),mod);for(int R=mid<<1,j=0;j<lim;j+=R){int w=1;for(ll k=0;k<mid;k++,w=(ll)w*W%mod){int x=A[j+k],y=(ll)w*A[j+k+mid]%mod;A[j+k]=(x+y)%mod;A[j+mid+k]=(x-y+mod)%mod;}}}if(type==-1){reverse(A+1,A+lim);int inv=ksm(lim,mod-2,mod);for(int i=0;i<lim;i++) A[i]=(ll)A[i]*inv%mod;}
}LL mi[M],has1[M],has2[M];
int a[M],b[M],c[M],n,ans,f[M];
char s[M],ss[M];const int h=31;
LL gethas1(int x,int y){return has1[y]-has1[x-1]*mi[y-x+1];}
LL gethas2(int x,int y){return has2[x]-has2[y+1]*mi[y-x+1];}
int query1(int x){int l=1,r=min(x,n-x);while(l<=r){int mid=(l+r)>>1;if(gethas1(x-mid,x+mid)==gethas2(x-mid,x+mid)) l=mid+1;else r=mid-1;}return r;
}
int query2(int x){int l=1,r=min(x,n-x);while(l<=r){int mid=(l+r)>>1;if(gethas2(x-mid+1,x+mid)==gethas1(x-mid+1,x+mid)) l=mid+1;else r=mid-1;}return r;
}
int getans(){int maxn=0;mi[0]=1;for(int i=1;i<=n;i++){has1[i]=has1[i-1]*h+(s[i-1]-'a'+1);mi[i]=mi[i-1]*h;}for(int i=n;i>=1;i--) has2[i]=has2[i+1]*h+(s[i-1]-'a'+1);for(int i=1;i<=n;i++)maxn=(ll)((ll)(maxn+query1(i))%p+query2(i))%p;return (maxn+n)%p;
}int manacher(){int res=0,cnt=0;ss[cnt]='$',ss[++cnt]='%';for(int i=0;i<n;i++) ss[++cnt]=s[i],ss[++cnt]='%';int mid=1,mr=1;for(int i=1;i<=cnt;i++){f[i]=min(mr-i,f[mid*2-i]);while(ss[i+f[i]]==ss[i-f[i]]) f[i]++;if(i+f[i]>mr) mr=i+f[i],mid=i;res=(res+f[i]/2)%p;}return res;
}signed main(){scanf("%s",s);n=strlen(s);for(int i=0;i<n;i++) a[i]=(s[i]=='a');for(int i=0;i<n;i++) b[i]=(s[i]=='b');int lim=1,l=0;while(lim<n*2) lim<<=1,l++;for(int i=0;i<lim;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));ntt(a,lim,1),ntt(b,lim,1);for(int i=0;i<lim;i++) a[i]=(ll)a[i]*a[i]%mod;for(int i=0;i<lim;i++) b[i]=(ll)b[i]*b[i]%mod;ntt(a,lim,-1),ntt(b,lim,-1);//for(int i=0;i<lim;i++) printf("%d %d\n",a[i],b[i]);for(int i=0;i<n*2-1;i++){if(!(i&1)) if(s[i>>1]=='a') a[i]++;else b[i]++;a[i]>>=1,b[i]>>=1;ans=(ll)(ans+ksm(2,a[i]+b[i],p)-1)%p;}//printf("%d\n",ans%p);//printf("%d\n",getans());printf("%d\n",(ll)(ans-getans()+p)%p);return 0;
}

P4199-FFT,manacher相关推荐

  1. 【BZOJ3160】 万径人踪灭(FFT,manacher)

    前言 多项式真的很难♂啊qwq Solution 考虑求的是一个有间隔的回文串,相当于是: 总的答案-没有间隔的答案 考虑总的答案怎么计算?FFT卷一下就好了. 对于每一位字符,有两种取值,然后随便卷 ...

  2. mfcc中的fft操作_简化音频数据:FFT,STFT和MFCC

    mfcc中的fft操作 What we should know about sound. Sound is produced when there's an object that vibrates ...

  3. python实现FFT,IFFT

    利用蝶形算法实现fft,以及ifft:我的算法还不太完整,只能输入图片长宽为2**n的图片,要改进只需要根据输入的长宽进行补0,使得长宽都为2的整数倍: import math import cv2 ...

  4. 离散傅里叶变换DFT与FFT,MATLAB的FFT函数使用(原创)——如何使用fft()绘制出真正的频谱图像

    以前一直对MATLAB中fft()函数的使用一直存在疑惑,为什么要加一 些参数,并且如何确定这些参数,也查了许多资料,但很多都感觉只是 表面一说根本没有讲清其本质.但随着学习的推进,慢慢有所领悟,所 ...

  5. 用 python 实现FFT,绘制频谱图

    用 python 实现FFT,绘制频谱图 关键词 :fft , scipy 库, fftshift ,单边谱,双边谱,频谱泄露 目录 用 python 实现FFT,绘制频谱图 前言 代码 结果 总结和 ...

  6. 洛谷P4199 万径人踪灭(manacher+FFT)

    传送门 题目所求为所有的不连续回文子序列个数,可以转化为回文子序列数-回文子串数 回文子串manacher跑一跑就行了,考虑怎么求回文子序列数 我们考虑,如果$S_i$是回文子序列的对称中心,那么只要 ...

  7. 卷积,DFT,FFT,图像FFT,FIR 和 IIR 的物理意义

    卷积:  冲击信号会对线性系统产生冲击响应.  冲击信号可分解为平移度和幅度.其对线性系统的冲击响应可以分解为点点间的经平移和缩放的各个冲击响应的累加,通过卷积的表达式表示.  所谓的冲击响应,就是线 ...

  8. 【BZOJ2342】双倍回文,manacher+并查集优化

    Time:2016.08.16 Author:xiaoyimi 转载注明出处谢谢 传送门 思路: woc第一次写马拉车怎么这么蛋疼啊 p[i]表示以i为中点,能向增长的最多的回文长度的一半 比如&qu ...

  9. 卷积,DFT,FFT,图像FFT,FIR 和 IIR 的物理意义。

    个人感觉很不错的一篇文章 卷积:  冲击信号会对线性系统产生冲击响应.  冲击信号可分解为平移度和幅度.其对线性系统的冲击响应可以分解为点点间的经平移和缩放的各个冲击响应的累加,通过卷积的表达式表示. ...

  10. c代码实现 ifft运算_二维FFT,IFFT,c语言实现 | 学步园

    学习DIP第6天 网上关于FFT的实例有很多,具体也可以参照上一篇,其实Matlab,OpenCV都可以很轻松的实现相关操作,但是对于学习其原理,还是自己操作下比较好. 二维FFT的是实现方法是先对行 ...

最新文章

  1. 2020-10-29Ubuntu20.04将软件添加至桌面
  2. volatile和内存屏障(dmb)
  3. MySQL 数据库的操作 连接、新增、删除、选择数据库 命令行(带图)
  4. Oracle存储过程中跳出循环的写法
  5. python打开setting_Django自带日志 settings.py文件配置方法
  6. 程序异常异常代码: 0xc0000005_Java基础:看完这篇你还怕碰到异常吗?
  7. c语言 三个小球排排坐,关颖三个孩子排排坐 太萌啦
  8. 修改MySQL自动递增值
  9. React 小案例 路由跳转
  10. 7-5 全量复制和部分复制
  11. Vue.js 学习笔记 一
  12. 浅谈对POW的认识和理解
  13. 解决混淆报错问题-打包签名出现问题的解决方法
  14. 用Python实现手机抓包,获取当当图书差评数据!
  15. Windows 计算机上查看 DNS 缓存的方法
  16. mysql 截断多个表_如何从MySQL数据库中截断所有表?
  17. assertThat使用方法
  18. Vue3 +ts 打包后访问是空白页面
  19. 嵌入式开发要难于单片机开发?
  20. 《大话西游》经典对白

热门文章

  1. cxk不会二进制 (贪心)
  2. echarts绘制进度条
  3. 一篇文章让你搞懂Reflect和Reflect metadata(JavaScript)
  4. 聚合数据简易开发流程
  5. Multisim电路分析仿真-叠加原理
  6. winxp怎么打开无线网络服务器,WinXP无线网络设置的方法
  7. Java标准教程:Java 2D绘图--第4章 使用Text API
  8. 查看硬盘序列号的方法 和查看设备序列号的方法
  9. 双光耦开关电源电路图_开关电源电路图及原理讲解
  10. 用c语言表达圣诞节快乐的英文,双语:Merry Christmas 圣诞节快乐用英语怎么说