P4199-万径人踪灭【FFT】
正题
题目链接:https://www.luogu.com.cn/problem/P4199
题目大意
给出一个只包含\(a,b\)的字符串
求有多少个不连续的回文子序列(字母回文,位置对称)
\(1\leq n\leq 10^5\)
解题思路
这个不连续一看就很nt,考虑求出所有的再减去连续的
对于每个对称轴来说,\(a,b\)分开考虑贡献再乘起来再减去一(两个都为空)。
加入计算\(a\)的贡献,就是看有多少对\(a\)以它为对称轴,设为\(k\)对,那么方案就是\(2^k\)。
怎么对于每个对称轴快速计算有多少对?也就是每对\(a\)都会对他们的对称轴产生贡献,假设\(i\)于\(j\)都是\(a\),那么对称轴就是\(\frac{i+j}{2}\),这个直接\(FFT\)就可以了
然后\(b\)同理。
然后字符串hash+二分计算连续的方案就好了
时间复杂度\(O(n\log n)\)
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define ull unsigned long long
using namespace std;
const ll N=4e5+10,P=998244353,p=1e9+7;
const ull g=131;
ll n,l,a[N],b[N],r[N],ans;
ull pw[N],h[N],d[N];
char s[N];
ll power(ll x,ll b,ll P){
ll ans=1;
while(b){
if(b&1)ans=ans*x%P;
x=x*x%P;b>>=1;
}
return ans;
}
void NTT(ll *f,ll op){
for(ll i=0;i<n;i++)
if(i<r[i])swap(f[i],f[r[i]]);
for(ll p=2;p<=n;p<<=1){
ll tmp=power(3,(P-1)/p,P),len=(p>>1);
if(op==-1)tmp=power(tmp,P-2,P);
for(ll k=0;k<n;k+=p){
ll buf=1;
for(ll i=k;i<k+len;i++){
ll tt=buf*f[i+len]%P;
f[i+len]=(f[i]-tt+P)%P;
f[i]=(f[i]+tt)%P;
buf=buf*tmp%P;
}
}
}
if(op==-1){
ll invn=power(n,P-2,P);
for(ll i=0;i<n;i++)
f[i]=f[i]*invn%P;
}
return;
}
ull geth(ll l,ll r)
{return h[r]-h[l-1]*pw[r-l+1];}
ull getd(ll l,ll r)
{return d[l]-d[r+1]*pw[r-l+1];}
signed main()
{
scanf("%s",s);l=strlen(s);
for(ll i=0;i<l;i++)
a[i]=(s[i]=='a'),b[i]=(s[i]=='b');
n=1;while(n<2*l)n<<=1;
for(ll i=0;i<n;i++)r[i]=(r[i>>1]>>1)|((i&1)?(n>>1):0);
NTT(a,1);NTT(b,1);
for(ll i=0;i<n;i++)a[i]=a[i]*a[i]%P,b[i]=b[i]*b[i]%P;
NTT(a,-1);NTT(b,-1);
for(ll i=0;i<n;i++)a[i]=(a[i]+1)/2,b[i]=(b[i]+1)/2;
for(ll i=0;i<n;i++)
(ans+=power(2,a[i]+b[i],p)%p-1)%=p;
pw[0]=1;
for(ll i=1;i<=l;i++)pw[i]=pw[i-1]*g;
for(ll i=1;i<=l;i++)h[i]=h[i-1]*g+s[i-1]-'a';
for(ll i=l;i>=1;i--)d[i]=d[i+1]*g+s[i-1]-'a';
for(ll i=1;i<=l;i++){
ll L=1,R=min(i,l-i+1)-1;
while(L<=R){
ll mid=(L+R)>>1;
if(geth(i-mid,i+mid)==getd(i-mid,i+mid))L=mid+1;
else R=mid-1;
}
ans-=R+1;
}
for(ll i=1;i<l;i++){
ll L=1,R=min(i,l-i);
while(L<=R){
ll mid=(L+R)>>1;
if(geth(i-mid+1,i+mid)==getd(i-mid+1,i+mid))L=mid+1;
else R=mid-1;
}
ans-=R;
}
printf("%lld\n",(ans%p+p)%p);
return 0;
}
P4199-万径人踪灭【FFT】的更多相关文章
- P4199 万径人踪灭 FFT + manacher
\(\color{#0066ff}{ 题目描述 }\) \(\color{#0066ff}{输入格式}\) 一行,一个只包含a,b两种字符的字符串 \(\color{#0066ff}{输出格式}\) ...
- 洛谷P4199 万径人踪灭(manacher+FFT)
传送门 题目所求为所有的不连续回文子序列个数,可以转化为回文子序列数-回文子串数 回文子串manacher跑一跑就行了,考虑怎么求回文子序列数 我们考虑,如果$S_i$是回文子序列的对称中心,那么只要 ...
- BZOJ 3160: 万径人踪灭 [fft manacher]
3160: 万径人踪灭 题意:求一个序列有多少不连续的回文子序列 一开始zz了直接用\(2^{r_i}-1\) 总-回文子串 后者用manacher处理 前者,考虑回文有两种对称形式(以元素/缝隙作为 ...
- bzoj 3160 万径人踪灭 FFT
万径人踪灭 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1936 Solved: 1076[Submit][Status][Discuss] De ...
- BZOJ 3160: 万径人踪灭 FFT+快速幂+manacher
BZOJ 3160: 万径人踪灭 题目传送门 [题目大意] 给定一个长度为n的01串,求有多少个回文子序列? 回文子序列是指从原串中找出任意个,使得构成一个回文串,并且位置也是沿某一对称轴对称. 假如 ...
- 【bzoj3160】万径人踪灭 FFT
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3160 我是一个傻叉 微笑脸 #include<bits/stdc++.h> #de ...
- Luogu4199 万径人踪灭 FFT、Manacher
传送门 先不考虑”不是连续的一段“这一个约束条件.可以知道:第$i$位与第$j$位相同,可以对第$\frac{i+j}{2}$位置上产生$1$的贡献(如果$i+j$为奇数表明它会对一条缝产生$1$的贡 ...
- 【洛谷】P4199 万径人踪灭
题解 每种字符跑一遍FFT,得到\(i + j = k\)时匹配的个数(要÷2,对于相同位置的最后再加上 然后算出\(2^{cnt[k]}\)的和,最后再减去用mancher匹配出的连续回文子串的个数 ...
- BZOJ3160:万径人踪灭(FFT,Manacher)
Solution $ans=$回文子序列$-$回文子串的数目. 后者可以用$manacher$直接求. 前者设$f[i]$表示以$i$为中心的对称的字母对数. 那么回文子序列的数量也就是$\sum_{ ...
- luogu P4199 万径人踪灭
嘟嘟嘟 方案:回文子序列数 - 回文子串数. 回文子串数用manacher解决就行了,关键是怎么求会问序列数. 一个比较好的\(O(n ^ 2)\)的算法:对于一个回文中心\(i\),\(O(n)\) ...
随机推荐
- mfc HackerTools远程线程注入
在一个进程中,调用CreateThread或CreateRemoteThreadEx函数,在另一个进程内创建一个线程(因为不在同一个进程中,所以叫做远程线程).创建的线程一般为Windows API函 ...
- 【springcloud】客户端负载均衡(Ribbon)
转自:https://blog.csdn.net/pengjunlee/article/details/86594934 服务器端负载均衡负载均衡是我们处理高并发.缓解网络压力和进行服务器扩容的重要手 ...
- (强制)要求覆写equals必须覆写hashCode(原理分析)
hashCode和equals hashCode和equals用来标识对象,两个方法协同工作可用来判断两个对象是否相等.众所周知,根据生成的哈希将数据散列开来,可以使存取元素更快.对象通过调用Obje ...
- spring加载Bean的解析过程(二)
1.例如: BeanFactory bf = new XmlBeanFactory(new ClassPathResource("spring.xml")); User user ...
- 未解决的html页面banner对不齐
莫名其妙的问题,记录等待解决: 怎么讲呢?就是可能真的没有理解这句话,浏览器是否是需要这句话的,思考! <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML ...
- struts2思想学习(一)
OOP 面向对象编程 AOP 面向切面编程 而在struts2 处处体现了面向切面编程的思想(动态代理最典型)! 拦截器其实也是面向切面编程!拦截器切断了所有请求到action的操作 并做了很多的前提 ...
- go GC垃圾回收原理
目录 1.前言 2. 垃圾回收算法 3. Golang垃圾回收 3.1 垃圾回收原理 3.2 内存标记(Mark) 3.3 三色标记 3.4 Stop The World 4. 垃圾回收优化 4.1 ...
- Vue.JS快速上手(组件间的通信)
前言 Vue采用的是组件化思想,那么这些组件间是如何通信的呢?下面详细介绍一下. 所谓组件间通信,不单单是我们字面上理解的相互传递数据,这里还包括一个组件访问另一个组件的实例方法等,如父组件通过ref ...
- Ubuntu18.04下安装、测试tensorflow/models Tensorflow Object Detection API 笔记
参考:https://www.jianshu.com/p/1ed2d9ce6a88 安装 安装conda+tensorflow库 下载protoc linux x64版,https://github. ...
- 发布 mbtiles 存储的矢量瓦片
之前我们分享过如何 在本地发布OSM矢量瓦片地图,里面介绍了生成的矢量瓦片会存放在 .mbtiles 文件中,然后用 tileserver-gl 软件发布. mbtiles 是基于sqllite数据库 ...