Description

一个ab串,问有多少回文子序列,字母和位置都对称,并且不连续.

Sol

FFT+Manacher.

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

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

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

Code

  1. /**************************************************************
  2. Problem: 3160
  3. User: BeiYu
  4. Language: C++
  5. Result: Accepted
  6. Time:3868 ms
  7. Memory:29616 kb
  8. ****************************************************************/
  9.  
  10. #include <bits/stdc++.h>
  11. using namespace std;
  12.  
  13. #define mpr make_pair
  14. #define rr first
  15. #define ii second
  16. typedef pair< double,double > Complex;
  17. typedef long long LL;
  18. const int N = 5e5+50;
  19. const long long p = 1e9+7;
  20. const double Pi = M_PI;
  21.  
  22. Complex operator + (const Complex &a,const Complex &b) {
  23. return mpr(a.rr+b.rr,a.ii+b.ii);
  24. }
  25. Complex operator - (const Complex &a,const Complex &b) {
  26. return mpr(a.rr-b.rr,a.ii-b.ii);
  27. }
  28. Complex operator * (const Complex &a,const Complex &b) {
  29. return mpr(a.rr*b.rr-a.ii*b.ii,a.rr*b.ii+a.ii*b.rr);
  30. }
  31.  
  32. int n,l;
  33. LL ans;
  34. int f[N],g[N];
  35. char t[N],s[N];
  36. Complex a[N],b[N],c[N];
  37.  
  38. 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; }
  39. void Manacher(char *t) {
  40. int ll=0;
  41. for(int i=0;i<l;i++) s[ll++]='#',s[ll++]=t[i];
  42. s[0]='$',s[ll++]='@';
  43.  
  44. for(int i=0,j=0,mx=0;i<ll;i++) {
  45. if(mx>i) f[i]=min(mx-i,f[j*2-i]);else f[i]=1;
  46. while(i+f[i]<ll && i-f[i]>=0 && s[i+f[i]]==s[i-f[i]]) f[i]++;
  47. if(i+f[i]>mx) mx=i+f[i],j=i;
  48. }
  49. }
  50.  
  51. void init(int x) {
  52. for(n=1;n<x;n<<=1);n<<=1;
  53. }
  54. void Rev(Complex a[]) {
  55. for(int i=0,j=0;i<n;i++) {
  56. if(i>j) swap(a[i],a[j]);
  57. for(int k=n>>1;(j^=k)<k;k>>=1);
  58. }
  59. }
  60. void DFT(Complex a[],int r=1) {
  61. Rev(a);
  62. for(int i=2;i<=n;i<<=1) {
  63. Complex wi=mpr(cos(2.0*Pi/i),r*sin(2.0*Pi/i));
  64. for(int k=0;k<n;k+=i) {
  65. Complex w=mpr(1.0,0.0);
  66. for(int j=k;j<k+i/2;j++) {
  67. Complex t1=a[j],t2=w*a[j+i/2];
  68. a[j]=t1+t2,a[j+i/2]=t1-t2;
  69. w=w*wi;
  70. }
  71. }
  72. }
  73. if(r==-1) for(int i=0;i<n;i++) a[i].rr/=n;
  74. }
  75. void FFT(Complex a[],Complex b[],Complex c[]) {
  76. DFT(a),DFT(b);
  77. for(int i=0;i<n;i++) c[i]=a[i]*b[i];
  78. DFT(c,-1);
  79. }
  80.  
  81. int main() {
  82. scanf("%s",t);
  83. l=strlen(t);
  84. init(l);
  85. for(int i=0;i<l;i++) a[i]=mpr(t[i]=='a',0),b[i]=a[i];
  86. // reverse(b,b+l);
  87.  
  88. // for(int i=0;i<n;i++) cout<<(int)a[i].rr<<" ";cout<<endl;
  89. // for(int i=0;i<n;i++) cout<<(int)b[i].rr<<" ";cout<<endl;
  90.  
  91. FFT(a,b,c);
  92.  
  93. for(int i=0;i<n;i++) g[i]=(int)(c[i].rr+0.5);
  94. // for(int i=0;i<n;i++) cout<<(int)(c[i].rr+0.5)<<" ";cout<<endl;
  95.  
  96. memset(a,0,sizeof(a)),memset(b,0,sizeof(b));
  97. for(int i=0;i<l;i++) a[i]=mpr(t[i]=='b',0),b[i]=a[i];
  98. // reverse(b,b+l);
  99.  
  100. // for(int i=0;i<n;i++) cout<<(int)a[i].rr<<" ";cout<<endl;
  101. // for(int i=0;i<n;i++) cout<<(int)b[i].rr<<" ";cout<<endl;
  102.  
  103. FFT(a,b,c);
  104.  
  105. for(int i=0;i<n;i++) g[i]+=(c[i].rr+0.5);
  106. // for(int i=0;i<n;i++) cout<<(int)(c[i].rr+0.5)<<" ";cout<<endl;
  107.  
  108. for(int i=0;i<n;i++) g[i]=(g[i]+1)/2;
  109. // for(int i=0;i<n;i++) cout<<g[i]<<" ";cout<<endl;
  110.  
  111. Manacher(t);
  112. // for(int i=0;i<n;i++) cout<<f[i]<<" ";cout<<endl;
  113.  
  114. for(int i=0;i<l*2+1;i++) if(!(i&1)) f[i]-=1;
  115. // for(int i=0;i<n;i++) cout<<f[i]<<" ";cout<<endl;
  116.  
  117. for(int i=0;i<l*2-1;i++) ans=(ans+Pow(2,g[i])-(f[i+1]+1)/2-1)%p;
  118.  
  119. cout<<ans<<endl;
  120.  
  121. return 0;
  122. }
  123. /*
  124. abaabaa
  125. 14
  126.  
  127. aaabbbaaa
  128. 44
  129.  
  130. aaaaaaaa
  131. 53
  132. */

  

BZOJ 3160: 万径人踪灭的更多相关文章

  1. BZOJ 3160: 万径人踪灭 FFT+快速幂+manacher

    BZOJ 3160: 万径人踪灭 题目传送门 [题目大意] 给定一个长度为n的01串,求有多少个回文子序列? 回文子序列是指从原串中找出任意个,使得构成一个回文串,并且位置也是沿某一对称轴对称. 假如 ...

  2. bzoj 3160: 万径人踪灭 manachar + FFT

    3160: 万径人踪灭 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 133  Solved: 80[Submit][Status][Discuss] ...

  3. BZOJ 3160: 万径人踪灭 [fft manacher]

    3160: 万径人踪灭 题意:求一个序列有多少不连续的回文子序列 一开始zz了直接用\(2^{r_i}-1\) 总-回文子串 后者用manacher处理 前者,考虑回文有两种对称形式(以元素/缝隙作为 ...

  4. bzoj 3160 万径人踪灭——FFT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3160 似乎理解加深了. 用卷积算相同的位置:先把 a 赋成1. b 赋成0,卷积一遍:再把 ...

  5. bzoj 3160 万径人踪灭 FFT

    万径人踪灭 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1936  Solved: 1076[Submit][Status][Discuss] De ...

  6. bzoj 3160 万径人踪灭 —— FFT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3160 求出关于一个位置有多少对对称字母,如果 i 位置有 f[i] 对,对答案的贡献是 2^ ...

  7. BZOJ 3160 万径人踪灭 解题报告

    这个题感觉很神呀.将 FFT 和 Manacher 有机结合在了一起. 首先我们不管那个 “不能连续” 的条件,那么我们就可以求出有多少对字母关于某一条直线对称,然后记 $T_i$ 为关于直线 $i$ ...

  8. bzoj 3160: 万径人踪灭【FFT+manacher】

    考虑正难则反,我们计算所有对称子序列个数,再减去连续的 这里减去连续的很简单,manacher即可 然后考虑总的,注意到关于一个中心对称的两点下标和相同(这样也能包含以空位为对称中心的方案),所以设f ...

  9. 【BZOJ 3160】 3160: 万径人踪灭 (FFT)

    3160: 万径人踪灭 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1440  Solved: 799 Description Input Outp ...

随机推荐

  1. SQL Server 中master..spt_values的应用

    今天在做数据分析报表的时候遇到一个这样的问题. 表结构如下.部门编码.部门名称.部门人员ID(中间用逗号分割) 我想通过和人员表链接,查询出一个新的数据集,查询出的结果集格式如下:人员信息(ID或者姓 ...

  2. 常用 Git 命令清单

    我每天使用 Git ,但是很多命令记不住. 一般来说,日常使用只要记住下图6个命令,就可以了.但是熟练使用,恐怕要记住60-100个命令. 下面是我整理的常用 Git 命令清单.几个专用名词的译名如下 ...

  3. 使用PrintDocument进行打印

    背景: 1.在winform中,需要直接调用打印机,进行打印处理 2.找了很多实现方法是web的处理,然后查了下度娘,发现可以使用自带类PrintDocument进行处理,所以就有了这篇文章 说明: ...

  4. html5定位getLocation()

    HTML5 Geolocation API 用于获得用户的地理位置. 如果用户不允许定位,那么用户信息是不可用的. 获取用户的位置:getCurrentPosition() 返回数据如下 返回用户当前 ...

  5. Reactjs+Webpack+es2015 入门HelloWord(一)

    链接,自己很久前总结的blog. https://my.oschina.net/tangyuanyu/blog/730265

  6. windows CMD下的命令

    1.  dir 列出当前目录的内容 2.  切换目录 C:\Users\shuyun>e: ## 切换主目录 E:\>cd DataCenter ## cd 切换子目录 E:\DataCe ...

  7. ADO.net

    五大对象: 1.Connection(连接数据库) 2.Command(执行T-SQL语句) 3.DataAdapter(用户填充DataSet,断开模式) 4.DataReader(读取数据库,一种 ...

  8. Java开发环境搭建——Idea开发环境

    Idea版本选择由于公司使用JDK7,所以我选择安装Version 2016.1.4(手动安装试验出来的,最新版的2016.1.4启动时提示需要安装JDK8)下载 其实可以安装多个版本的JDK,然后指 ...

  9. 【转载】STL之priority_queue

    参考资料:传送门先回顾队列的定义:队列(queue)维护了一组对象,进入队列的对象被放置在尾部,下一个被取出的元素则取自队列的首部.priority_queue特别之处在于,允许用户为队列中存储的元素 ...

  10. linux 主机名

    查看主机名命令:# uname -n csdba #hostname csdba 1.通过hostname命令.命令格式:hostname newhostname 此命令的作用是暂时的修改linux的 ...