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

本文介绍了一种使用快速傅立叶变换(FFT)处理字符串卷积的方法,通过将字符串转换为数值序列并利用FFT的高效计算能力,实现对回文串的计数。文章详细解释了如何通过字符集次将字符串映射到数值上,再通过FFT进行自我卷积,最终结合容斥原理和回文自动机来准确计算回文串的数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BZOJ传送门:

解题思路:

FFT在处理卷积时可以将自己与自己卷,在某一种字母上标1其他标0,做字符集次就好了。

(回文就是直接对称可以联系偶函数定义理解,根据这个性质就可以将字符串反向实现字符串匹配)。

最后利用容斥回文字符2的次幂-回文串就好了。

回文串计数当然要回文自动机了。

代码:

  1 #include<cmath>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 typedef long long lnt;
  6 const int maxn=362144;
  7 const double PI=acos(-1.0);
  8 const lnt mod=(lnt)(1e9+7);
  9 struct cp{
 10     double x,y;
 11     cp(){};
 12     cp(double a,double b){x=a,y=b;}
 13     cp friend operator + (cp a,cp b){return cp(a.x+b.x,a.y+b.y);}
 14     cp friend operator - (cp a,cp b){return cp(a.x-b.x,a.y-b.y);}
 15     cp friend operator * (cp a,cp b){return cp(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
 16 }A[maxn],B[maxn],C[maxn];
 17 struct PAM{
 18     struct pant{
 19         int tranc[2];
 20         int len;
 21         int pre;
 22         int wgt;
 23     }h[maxn];
 24     int siz;
 25     int fin;
 26     lnt ans;
 27     bool mis(char *a,int i,int lsp)
 28     {
 29         return a[i]!=a[i-h[lsp].len-1];
 30     }
 31     void Insert(char *a,int i)
 32     {
 33         int nwp,lsp,mac;
 34         lsp=fin;
 35         int c=a[i]-'a';
 36         while(mis(a,i,lsp))
 37             lsp=h[lsp].pre;
 38         if(!h[lsp].tranc[c])
 39         {
 40             nwp=++siz;
 41             mac=h[lsp].pre;
 42             h[nwp].len=h[lsp].len+2;
 43             while(mis(a,i,mac))
 44                 mac=h[mac].pre;
 45             h[nwp].pre=h[mac].tranc[c];
 46             h[lsp].tranc[c]=nwp;
 47             h[nwp].wgt=h[h[nwp].pre].wgt+1;
 48         }
 49         fin=h[lsp].tranc[c];
 50         ans+=h[fin].wgt;
 51         return ;
 52     }
 53     PAM(){}
 54     PAM(char *a,int n)
 55     {
 56         ans=0;
 57         siz=1;
 58         fin=0;
 59         h[1].pre=h[0].pre=1;
 60         h[1].len=-1;
 61         h[0].len=0;
 62         for(int i=1;i<=n;i++)
 63             Insert(a,i);
 64     }
 65     lnt val(void)
 66     {
 67         return ans;
 68     }
 69 };
 70 int lim;
 71 int len;
 72 int n,m;
 73 int pos[maxn];
 74 lnt pow2[maxn];
 75 char str[maxn];
 76 void getpos(void)
 77 {
 78     for(int i=0;i<len;i++)
 79         pos[i]=(pos[i>>1]>>1)|((i&1)<<(lim-1));
 80     return ;
 81 }
 82 void Fft(cp *a,double flag)
 83 {
 84     for(int i=0;i<len;i++)
 85         if(i<pos[i])
 86             std::swap(a[i],a[pos[i]]);
 87     for(int i=2;i<=len;i<<=1)
 88     {
 89         cp wn(cos(2.00*PI*flag/(double)(i)),sin(2.00*PI*flag/(double)(i)));
 90         for(int j=0;j<len;j+=i)
 91         {
 92             cp w(1.00,0.00),t;
 93             for(int k=0;k<(i>>1);k++,w=w*wn)
 94             {
 95                 t=a[k+j+(i>>1)]*w;
 96                 a[j+k+(i>>1)]=a[j+k]-t;
 97                 a[j+k]=a[j+k]+t;
 98             }
 99         }
100     }
101     return ;
102 }
103 int main()
104 {
105     scanf("%s",str+1);
106     int lth=strlen(str+1);
107     for(int i=1;i<=lth;i++)
108         if(str[i]=='a')
109             A[i-1].x=1.00;
110         else
111             B[i-1].x=1.00;
112     while((1<<lim)<(lth<<1))
113         lim++;
114     len=1<<lim;
115     getpos();
116     Fft(A,1);
117     Fft(B,1);
118     for(int i=0;i<len;i++)
119         A[i]=A[i]*A[i]+B[i]*B[i];
120     Fft(A,-1);
121     pow2[0]=1;
122     for(int i=1;i<=len;i++)
123         pow2[i]=pow2[i-1]*2ll%mod;
124     lnt ans=0;
125     for(int i=0;i<len;i++)
126         ans=(ans+pow2[((lnt)(A[i].x/(double)(len)+0.5)+1ll)/2]-1ll)%mod;
127     PAM P(str,lth);    
128         ans=((ans-P.val())%mod+mod)%mod;
129     printf("%lld\n",ans);
130     return 0;
131 }   

 

转载于:https://www.cnblogs.com/blog-Dr-J/p/10085150.html

内容概要:本文针对国内加密货币市场预测研究较少的现状,采用BP神经网络构建了CCi30指数预测模型。研究选取2018年3月1日至2019年3月26日共391天的数据作为样本,通过“试凑法”确定最优隐结点数目,建立三层BP神经网络模型对CCi30指数收盘价进行预测。论文详细介绍了数据预处理、模型构建、训练及评估过程,包括数据归一化、特征工程、模型架构设计(如输入层、隐藏层、输出层)、模型编译与训练、模型评估(如RMSE、MAE计算)以及结果可视化。研究表明,该模型在短期内能较准确地预测指数变化趋势。此外,文章还讨论了隐层节点数的优化方法及其对预测性能的影响,并提出了若干改进建议,如引入更多技术指标、优化模型架构、尝试其他时序模型等。 适合群:对加密货币市场预测感兴趣的研究员、投资者及具备一定编程基础的数据分析师。 使用场景及目标:①为加密货币市场投资者提供一种新的预测工具和方法;②帮助研究员理解BP神经网络在时间序列预测中的应用;③为后续研究提供改进方向,如数据增强、模型优化、特征工程等。 其他说明:尽管该模型在短期内表现出良好的预测性能,但仍存在一定局限性,如样本量较小、未考虑外部因素影响等。因此,在实际应用中需谨慎对待模型预测结果,并结合其他分析工具共同决策。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值