Bzoj3160:万径人踪灭
题面
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:万径人踪灭的更多相关文章
- [bzoj3160]万径人踪灭_FFT_Manacher
万径人踪灭 bzoj-3160 题目大意:给定一个ab串.求所有的子序列满足:位置和字符都关于某条对称轴对称而且不连续. 注释:$1\le n\le 10^5$. 想法: 看了大爷的题解,OrzOrz ...
- BZOJ3160 万径人踪灭 字符串 多项式 Manachar FFT
原文链接http://www.cnblogs.com/zhouzhendong/p/8810140.html 题目传送门 - BZOJ3160 题意 给你一个只含$a,b$的字符串,让你选择一个子序列 ...
- BZOJ3160 万径人踪灭(FFT+manacher)
容易想到先统计回文串数量,这样就去掉了不连续的限制,变为统计回文序列数量. 显然以某个位置为对称轴的回文序列数量就是2其两边(包括自身)对称相等的位置数量-1.对称有啥性质?位置和相等.这不就是卷积嘛 ...
- BZOJ3160万径人踪灭
Description Input & Output & Sample Input & Sample Output HINT 题解: 题意即求不连续但间隔长度对称的回文串个数. ...
- BZOJ3160: 万径人踪灭
设a[i]=bool(s[i]=='a'),b[i]=bool(s[i]=='b'),考虑a和a.b和b的卷积,由于卷积是对称的,就可以统计出不连续回文子串个数了.可能说得比较简略.再用manache ...
- bzoj千题计划302:bzoj3160: 万径人踪灭
https://www.lydsy.com/JudgeOnline/problem.php?id=3160 不连续的回文串数量=所有的回文序列数量-连续的回文子串 连续的回文子串: manacher ...
- BZOJ3160:万径人踪灭(FFT,Manacher)
Solution $ans=$回文子序列$-$回文子串的数目. 后者可以用$manacher$直接求. 前者设$f[i]$表示以$i$为中心的对称的字母对数. 那么回文子序列的数量也就是$\sum_{ ...
- BZOJ3160 万径人踪灭 【fft + manacher】
题解 此题略神QAQ orz po神牛 由题我们知道我们要求出: 回文子序列数 - 连续回文子串数 我们记为ans1和ans2 ans2可以用马拉车轻松解出,这里就不赘述了 问题是ans1 我们设\( ...
- BZOJ3160: 万径人踪灭(FFT,回文自动机)
BZOJ传送门: 解题思路: FFT在处理卷积时可以将自己与自己卷,在某一种字母上标1其他标0,做字符集次就好了. (回文就是直接对称可以联系偶函数定义理解,根据这个性质就可以将字符串反向实现字符串匹 ...
- 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/常用套路【入门】
原文链接https://www.cnblogs.com/zhouzhendong/p/Fast-Fourier-Transform.html 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/ ...
随机推荐
- weblogic修改jdk版本遇到的问题与解决方法
1.修改setDomainEnv ,路径.../domains/xx_domain\bin\ 1.1修改JAVA_HOME为需要修改的路径 注意:BEA_JAVA_HOME路径不需修改 2.修改路径后 ...
- shell脚本实现nfs服务安装配置,共享文件分发
##############################Deploy nfs######################## echo "start deploy nfs-server& ...
- Go语言极速入门手册
Github: https://github.com/coderzh/CodeTips /* gotips_test.go: Golang速学速查速用代码手册 Source: github.com/c ...
- Java中的双重检查锁(double checked locking)
最初的代码 在最近的项目中,写出了这样的一段代码 private static SomeClass instance; public SomeClass getInstance() { if (nul ...
- Java经典编程题50道之四十九
计算某字符串中子串出现的次数. public class Example49 { public static void main(String[] args) { String s ...
- 使用docker搭建wordpress
前言 去年在学习docker,在看完菜鸟教程和第一本docker书后,一直想实战用一下这个技术,多用用才能熟能生巧,真正体验它的利弊.正好傅老板用docker搭完了wordpress,我也就手痒跟着搭 ...
- Hibernate学习(五)lazy属性学习(true和extra区别)
Lazy(懒加载)在hibernate何处使用:1.<class>标签上,可以取值:true/false,(默认值是:true)2.<property>标签上,可以取值:tru ...
- Qt Create or VS 2015 使用 Opencv330 相机静态库链接错误如何解决?
查看链接库,添加 vfw32.lib 即可.
- ANTD mobile源码分析 -- popover
最近的开发中要用到很多的各式各样的组件.但是发现ant design mobile(后面简称ANTDM)里很多的资源.于是就分析一下,学习学习. ANTDM直接使用了typescript,没有用ES2 ...
- iOS 开发之字典写入文件
在最近的开发中阿,遇到一个问题,是我开始没有注意到的问题,某个羡慕后期维护的过程中发现一个bug,这个bug就是关于字典写入文件的.缘由是这样的,我用字典写入文件的方法 BOOL result = [ ...