UVALive4671   K-neighbor substrings   给定一个两个字符串A和B B为模式串。问A中有多少不同子串与B的距离小于k 所谓距离就是不同位的个数。

由于字符串只包含a和b 我们可以换做0和1 将B反转 进行大整数乘法(卷积) 就可以轻松得出不同的位数。只有FFT能在nlogn时间内完成大整数乘法。

要求不同的子串,再进行一次字符串散列即可。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<vector>
  7. #include<map>
  8. #include<set>
  9. #include<algorithm>
  10. #include<queue>
  11. #include<stack>
  12. #include<complex>
  13. //使用FFT时注意精度问题和数组大小
  14. using namespace std;
  15. typedef long long int LL;
  16. const double pi=acos(-1.0);
  17. struct Complex {
  18. double r, i;
  19. Complex(double _r, double _i) {
  20. r = _r;
  21. i = _i;
  22. }
  23. double real()
  24. {
  25. return r;
  26. }
  27. double ii()
  28. {
  29. return i;
  30. }
  31. Complex operator + (const Complex &c) {
  32. return Complex(c.r + r, c.i + i);
  33. }
  34. Complex operator - (const Complex &c) {
  35. return Complex(r - c.r, i - c.i);
  36. }
  37. Complex operator * (const Complex &c) {
  38. return Complex(c.r * r - c.i * i, c.r * i + c.i * r);
  39. }
  40. Complex operator / (const int &c) {
  41. return Complex(r / c, i / c);
  42. }
  43. Complex(){}
  44. };
  45. void build(Complex _P[],Complex P[],LL n,LL m,LL curr,LL &cnt)
  46. {
  47. if(n==m){_P[curr]=P[cnt++];}
  48. else {build(_P,P,n,m*2,curr,cnt);build(_P,P,n,m*2,curr+m,cnt);}
  49.  
  50. }
  51. const LL maxn=300000;
  52. void FFT(Complex P[],LL n,LL oper)//返回结果向左靠齐 最后结果除n
  53. {
  54. static Complex _P[maxn];
  55. LL cnt=0;
  56. build(_P,P,n,1,0,cnt);copy(_P,_P+n,P);
  57. for(LL d=0;(1<<d)<n;d++)
  58. {
  59. LL m=1<<d;
  60. LL m2=m*2;
  61. double p0=pi/m*oper;
  62. Complex unit_p0=Complex(cos(p0),sin(p0));
  63. for(LL i=0;i<n;i+=m2)
  64. {
  65. Complex unit=Complex(1,0);
  66. for(LL j=0;j<m;j++)
  67. {
  68. Complex &P1=P[i+j+m],&P2=P[i+j];
  69. Complex t=unit*P1;
  70. P1=P2-t;
  71. P2=P2+t;
  72. unit=unit*unit_p0;
  73. }
  74. }
  75. }
  76. }
  77. void himult(Complex p1[],Complex p2[],LL n,Complex ans[])
  78. {
  79.  
  80. FFT(p1,n,1);FFT(p2,n,1);
  81. for(LL i=0;i<=n;i++)
  82. ans[i]=p1[i]*p2[i];
  83. FFT(ans,n,-1);
  84. }
  85. char a[131072*2],b[131072*2];
  86. Complex av[131072*4],bv[131072*2+1],ans1[131072*2+1];
  87. unsigned long long int ha[200000],xp[200000];
  88. const int seed=3;
  89. set<unsigned long long int >vise;
  90. bool hash(int l,int r)
  91. {
  92. unsigned long long int nowv= ha[r+1]-ha[l]*xp[r-l+1];
  93. if(vise.count(nowv)==0){vise.insert(nowv);return false;}
  94. else return true;
  95. }
  96. int main()
  97. {
  98. freopen("t.txt","r",stdin);
  99. xp[0]=1;
  100. for(int i=1;i<=100000;i++)
  101. xp[i]=xp[i-1]*seed;
  102. int ii=0;
  103. while(1)
  104. { ii++;
  105. vise.clear();
  106. int k;
  107. scanf("%d",&k);
  108. if(k==-1)break;
  109. memset(a,0,sizeof(a));memset(b,0,sizeof(b));
  110. scanf("%s%s",&a,&b);
  111. int la=strlen(a),lb=strlen(b);
  112. int len=1;
  113. while(len<=la+lb)len<<=1;
  114. for(int i=0;i<la;i++)
  115. av[i]=Complex(a[i]=='a'?1:-1,0);
  116. for(int i=la;i<=len;i++)av[i]=Complex(0,0);
  117. for(int i=0;i<lb;i++)
  118. bv[lb-i-1]=Complex(b[i]=='a'?1:-1,0);
  119. for(int i=lb;i<=len;i++)
  120. bv[i]=Complex(0,0);
  121. memset(ans1,0,sizeof(ans1));
  122. himult(av,bv,len,ans1);
  123. int anss=0;
  124. ha[0]=0;
  125. for(int i=0;i<la;i++)
  126. ha[i+1]=ha[i]*seed+a[i];
  127. for(int i=0;i+lb<=la;i++)
  128. {
  129. if(hash(i,i+lb-1))continue;
  130. int nue=(int)(ans1[i+lb-1].r/len+0.5);
  131. if(lb-nue<=k*2)anss++;
  132. }
  133. printf("Case %d: %d\n",ii,anss);
  134. }
  135. return 0;
  136. }

  

UVALive 4671 K-neighbor substrings 巧用FFT的更多相关文章

  1. UVALive 7721 K - 2-ME Set 集合dp,所有数的位或来表示状态。

    /** 题目:UVALive 7721 K - 2-ME Set 链接:https://vjudge.net/problem/UVALive-7721 题意:给定n个数,从中取出一个集合,至少包含两个 ...

  2. UVALive - 4671 K-neighbor substrings (FFT+哈希)

    题意:海明距离的定义:两个相同长度的字符串中不同的字符数.现给出母串A和模式串B,求A中有多少与B海明距离<=k的不同子串 分析:将字符a视作1,b视作0.则A与B中都是a的位置乘积是1.现将B ...

  3. UVALive - 6886 Golf Bot 多项式乘法(FFT)

    题目链接: http://acm.hust.edu.cn/vjudge/problem/129724 Golf Bot Time Limit: 15000MS 题意 给你n个数,m个查询,对于每个查询 ...

  4. loj #6247. 九个太阳 k次单位根 神仙构造 FFT求和原理

    LINK:九个太阳 不可做系列. 构造比较神仙. 考虑FFT的求和原理有 \(\frac{1}{k}\sum_{j=0}^{k-1}(w_k^j)^n=[k|n]\) 带入这道题的式子. 有\(\su ...

  5. UVALive - 6257 K - Chemist's vows 【DFS】【BFS】【DP】

    题目链接 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  6. CodeForces - 528D Fuzzy Search (FFT求子串匹配)

    题意:求母串中可以匹配模式串的子串的个数,但是每一位i的字符可以左右偏移k个位置. 分析:类似于 UVALive -4671. 用FFT求出每个字符成功匹配的个数.因为字符可以偏移k个单位,先用尺取法 ...

  7. 快速傅里叶变换FFT

    多项式乘法 #include <cstdio> #include <cmath> #include <algorithm> #include <cstdlib ...

  8. 用于ARM上的FFT与IFFT源代码(C语言,不依赖特定平台)(转)

    源:用于ARM上的FFT与IFFT源代码(C语言,不依赖特定平台) 代码在2011年全国电子大赛结束后(2011年9月3日)发布,多个版本,注释详细. /*********************** ...

  9. FFT\NTT总结

    学了好久,终于基本弄明白了 推荐两个博客: 戳我 戳我 再推荐几本书: <ACM/ICPC算法基础训练教程> <组合数学>(清华大学出版社) <高中数学选修> 预备 ...

随机推荐

  1. 04JavaScript程序语句

    JavaScript程序语句 2.6程序控制流程 2.6.1选择结构 if <逻辑表达式> 语句 else 语句 if <逻辑表达式> { 语句组 } else { 语句组} ...

  2. reversed()函数和sorted()函数

    #reversed()反转排序,可对列表.元组.区间等进行排序 #练习1 a = range(10) a_list = [x for x in reversed(a)] print(a_list) # ...

  3. jquery 实现点评标签 类似淘宝大众点评的 快速准时 货品完好等

    111 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <tit ...

  4. enote笔记语言(5)——其他(ver0.2)

    章节:其他   ((主:单词))                               用来醒目地强调这个句子中哪个词语作主语 sentence:                         ...

  5. UVA-127 "Accordian" Patience(模拟)

    题目: 把52张牌从左到右排好,每张牌自成一个牌堆.当某张牌与它左边那张牌或者左边第三张牌匹配时(花色或者点数相同)时,就把这张牌移到那张牌上面. 移动之后还要查看是否可以进行其他移动.只有位于牌堆顶 ...

  6. MySQL5

    MySQL数据库5 mysqldump备份恢复数据库 冷备份还原数据库 逻辑卷快照备份还原数据库 xtrabackup备份还原数据库 1. 备份和恢复概述 适用场景 硬件故障.软件故障.自然灾害.黑客 ...

  7. Vmware下的Linux系统,安装WPS报错:[Errno 256] No more mirrors to try

    最近新装了虚拟环境Vmware下的Linux系统,准备看doc文档发现不能读取,才想起来一起都是重新开始的~没别的~开始安装吧: 1.关虚拟机Linux,添加cdrom镜像ISO文件--开虚拟机--- ...

  8. RAII手法封装互斥锁

    RAII手法是 Resource Acquisition is Initialization 的缩写,意为“资源获取即初始化”,在使用智能指针时也使用,下面是针对互斥量时的实现, #include & ...

  9. 【瞎扯】 About Me

    手动博客搬家: 本文发表于20181218 13:54:31, 原地址https://blog.csdn.net/suncongbo/article/details/85063885 来了?坐,欢迎来 ...

  10. redis学习——系统管理

    Redis系统管理 实验简介 上一节实验讲述了Redis的基本数据类型,本实验继续讲解Redis相关命令及管理操作. 在Redis中,命令大小写不敏感. 一.适合全体类型的常用命令 启动redis服务 ...