热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

BZOJ3160:万径人踪灭

FFT+Manacher.

FFT+Manacher.



不连续只需要减去连续的就可以了,连续的可以直接Manacher算出来.

其他全部对称的回文子序列就可以用生成函数那样FFT搞出来,把ab分开考虑就行.



有挺多细节的...包括下标运算什么什么的...

/**************************************************************
Problem: 3160
User: BeiYu
Language: C++
Result: Accepted
Time:3868 ms
Memory:29616 kb
****************************************************************/
#include bits/stdc++.h
using namespace std;
#define mpr make_pair
#define rr first
#define ii second
typedef pair double,double Complex;
typedef long long LL;
const int N = 5e5+50;
const long long p = 1e9+7;
const double Pi = M_PI;
Complex operator + (const Complex a,const Complex b) {
return mpr(a.rr+b.rr,a.ii+b.ii);
}
Complex operator - (const Complex a,const Complex b) {
return mpr(a.rr-b.rr,a.ii-b.ii);
}
Complex operator * (const Complex a,const Complex b) {
return mpr(a.rr*b.rr-a.ii*b.ii,a.rr*b.ii+a.ii*b.rr);
int n,l;
LL ans;
int f[N],g[N];
char t[N],s[N];
Complex a[N],b[N],c[N];
LL Pow(LL a,LL b,LL r=1) { for(;b;b =1,a=a*a%p) if(b 1) r=r*a%p;return r; }
void Manacher(char *t) {
int ll=0;
for(int i=0;i i++) s[ll++]='#',s[ll++]=t[i];
s[0]='$',s[ll++]='@';
for(int i=0,j=0,mx=0;i i++) {
if(mx i) f[i]=min(mx-i,f[j*2-i]);else f[i]=1;
while(i+f[i] ll i-f[i] =0 s[i+f[i]]==s[i-f[i]]) f[i]++;
if(i+f[i] mx) mx=i+f[i],j=i;
}
void init(int x) {
for(n=1;n n =1);n =1;
}
void Rev(Complex a[]) {
for(int i=0,j=0;i i++) {
if(i j) swap(a[i],a[j]);
for(int k=n 1;(j^=k) k =1);
}
}
void DFT(Complex a[],int r=1) {
Rev(a);
for(int i=2;i i =1) {
Complex wi=mpr(cos(2.0*Pi/i),r*sin(2.0*Pi/i));
for(int k=0;k k+=i) {
Complex w=mpr(1.0,0.0);
for(int j=k;j k+i/2;j++) {
Complex t1=a[j],t2=w*a[j+i/2];
a[j]=t1+t2,a[j+i/2]=t1-t2;
w=w*wi;
}
}
}
if(r==-1) for(int i=0;i i++) a[i].rr/=n;
}
void FFT(Complex a[],Complex b[],Complex c[]) {
DFT(a),DFT(b);
for(int i=0;i i++) c[i]=a[i]*b[i];
DFT(c,-1);
int main() {
scanf("%s",t);
l=strlen(t);
init(l);
for(int i=0;i i++) a[i]=mpr(t[i]=='a',0),b[i]=a[i];
// reverse(b,b+l);
// for(int i=0;i i++) cout (int)a[i].rr " ";cout endl;
// for(int i=0;i i++) cout (int)b[i].rr " ";cout endl;
FFT(a,b,c);
for(int i=0;i i++) g[i]=(int)(c[i].rr+0.5);
// for(int i=0;i i++) cout (int)(c[i].rr+0.5) " ";cout endl;
memset(a,0,sizeof(a)),memset(b,0,sizeof(b));
for(int i=0;i i++) a[i]=mpr(t[i]=='b',0),b[i]=a[i];
// reverse(b,b+l);
// for(int i=0;i i++) cout (int)a[i].rr " ";cout endl;
// for(int i=0;i i++) cout (int)b[i].rr " ";cout endl;
FFT(a,b,c);
for(int i=0;i i++) g[i]+=(c[i].rr+0.5);
// for(int i=0;i i++) cout (int)(c[i].rr+0.5) " ";cout endl;
for(int i=0;i i++) g[i]=(g[i]+1)/2;
// for(int i=0;i i++) cout g[i] " ";cout endl;
Manacher(t);
// for(int i=0;i i++) cout f[i] " ";cout endl;
for(int i=0;i l*2+1;i++) if(!(i 1)) f[i]-=1;
// for(int i=0;i i++) cout f[i] " ";cout endl;
for(int i=0;i l*2-1;i++) ans=(ans+Pow(2,g[i])-(f[i+1]+1)/2-1)%p;
cout ans endl;
return 0;
}
/*
abaabaa
#bbb#
##aa
53


   



推荐阅读
  • [二分图]JZOJ 4612 游戏
    DescriptionInputOutputSampleInput44#****#****#*xxx#SampleOutput5DataConstraint分析非常眼熟࿰ ... [详细]
  • Educational Codeforces Round 43 (Rated for Div. 2)
    EducationalCodeforcesRound43(RatedforDiv.2)https:codeforces.comcontest976A ... [详细]
  • 水题。。main.cppPATA1121CreatedbyPhoenixon2018224.Copyright©2018年Phoenix.Allrightsreserve ... [详细]
  • P1144 最短路计数· BFS/dijkstra
    题解其实题目很简单不写了,这里总结一下从这道题目里学到的知识:当最短路的边权都是1时,dijkstraspfa就是BFS如果使用优先队列,内部结构是pair时 ... [详细]
  • wyh2000andastringproblemTimeLimit:20001000MS(JavaOthers)MemoryLimit:13107265 ... [详细]
  • 883.三维形体投影面积
    题目883.三维形体投影面积题目大意在nxn的网格grid中,我们放置了一些与x,y,z三轴对齐的1x1x1立方体。每个值vgri ... [详细]
  • c语言自定义BOOL函数C语言没有BOOL类型变量boolean类型是C++所独有的由于使用BOOL类型可以使代码更具有可读性,很多编程者都在C中自己定义了类似的应用,一般方法有两 ... [详细]
  • Matlab中利用mex编译Opencv实现画板绘图功能
    图形绘制是标记和可视化数据的重要方法.通过在Matlab中集成画板绘图功能,可为科学计算提供便利.1设置Matlab支持Opencv编译操作系统:麒麟14.04(基于Ubu ... [详细]
  • 使用临时文件tmpnam该函数的功能是产生一个唯一的文件名系统回味该文件分配一块内存来保存临时变量例如下面的代码#includeintmain(){charnam ... [详细]
  • 这篇文章主要讲解了“GradeBook类怎么定义”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Grad ... [详细]
  • 原题我们定义“区间的价值”为一段区间的最大值*最小值。一个区间左端点在L,右端点在R,那么该区间的长度为(R−L+1)。求长度分别为1~n的区间的最大价值。保证数据随机因为保证数据随 ... [详细]
  • 【题意】点击打开链接【分析&解题思路】除去起点(1,1)和终点(n,m)已经固定,中间能经过的是一个(n-2)*(m-2)的矩阵然后我们可以在这个矩阵里取0个(就是直接从起点跳到 ... [详细]
  • socket8 [命名管道]
    ::命名管道不但能实现同一台机器上两个进程通信,还能在网络中不同机器上的两个进程之间的通信机制。与邮槽不同,命名管道是采用基于连接并且可靠的传输方式,所以命名管道传输数据只能一对一 ... [详细]
  • 实验七、绕过ASLR 第二部分
    7.1实验环境VM配置:Ubuntu12.04(x86)7.2实验原理什么是爆破?使用爆破技巧,来绕过共享库地址随机化。7.3实验过程7. ... [详细]
  • 编译lib手动编译cmake编译gtest测试程序断言和caseFixture使用gmock编译gmock测试程序参考GtestGithub使用gtest(gmock)方便我们编写 ... [详细]
author-avatar
惜洛妍_311
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有