题目

神题。

记得当初DYF和HZA讲过一个FFT+KMP的题目,一直觉得很神,从来没去做。

没有真正理解FFT的卷积。

首先考虑暴力。

只考虑前7位 KMP 找出所有 B 串可以匹配 A 串的位置。

设 a(i) = A(i) & 1, b(i) = B(i) & 1

然后相当于求所有的

c(i) =  ∑k=0m-1 a(i+k) * b(k)

考虑卷积形式:

c(i) =  ∑k=0m-1 a(k) * b(i - k)

将b串反过来

c(i) = ∑k=0m-1  a(k) * b(m-i+k)

改变 c 的定义令原先的 C(i) = 现在的 c(i+m)

得到 C(i) = ∑k=0m-1  a(k) * b(k-i)

所以 C(i) = ∑k=0m  a(k) * b(i-k+n)

然后FFT解决。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. #include <complex>
  5. #include <cmath>
  6.  
  7. #define N 250010
  8. #define Ex complex<double>
  9. #define pi 3.14159265354
  10.  
  11. using namespace std;
  12.  
  13. int n,m,a[N],b[N],same[N],rev[N<<];
  14.  
  15. inline void scan(int &x){
  16. char tmp[];
  17. scanf("%s",tmp);
  18. x=;
  19. int len=strlen(tmp);
  20. for(int i=len-;~i;i--)
  21. if(tmp[i]=='') x|=(<<(len-i-));
  22. }
  23.  
  24. inline bool simple(int a,int b){
  25. return (a|)==(b|);
  26. }
  27.  
  28. int f[N];
  29. bool match[N];
  30. Ex A[N<<],B[N<<],C[N<<];
  31.  
  32. void fft(Ex x[],int n,int t){
  33. for(int i=;i<n;i++){
  34. if(rev[i]>i) swap(x[rev[i]],x[i]);
  35. }
  36. for(int m=;m<n;m<<=){
  37. Ex wn(cos(pi/m*t),sin(pi/m*t));
  38. for(int k=;k<n;k+=(m<<)){
  39. Ex wt(,);
  40. for(int i=;i<m;i++,wt*=wn){
  41. Ex &A=x[i+m+k],&B=x[i+k],tmp=wt*A;
  42. A=B-tmp; B=B+tmp;
  43. }
  44. }
  45. }
  46. if(t==-){
  47. for(int i=;i<n;i++)
  48. x[i]/=(double)n;
  49. }
  50. }
  51.  
  52. int main(){
  53. freopen("message10.in","r",stdin);
  54. scanf("%d%d",&n,&m);
  55. for(int i=;i<n;i++) scan(a[i]);
  56. for(int i=;i<m;i++) scan(b[i]);
  57. f[]=f[]=;
  58. for(int i=;i<m;i++){
  59. int j=f[i];
  60. while(j&&!simple(b[i],b[j])) j=f[j];
  61. f[i+]= simple(b[i],b[j])? j+:;
  62. }
  63. int j=;
  64. bool flag=;
  65. for(int i=;i<n;i++){
  66. while(j&&!simple(b[j],a[i])) j=f[j];
  67. if(simple(b[j],a[i])) j++;
  68. if(j==m) match[i-m+]=,flag=;
  69. }
  70. if(!flag){
  71. puts("No");
  72. return ;
  73. }
  74. puts("Yes");
  75. int T=,nt;
  76. for(nt=;nt<=(n+m);nt<<=) T++;
  77. for(int i=;i<nt;i++) rev[i]=(rev[i>>]>>)|((i&)<<(T-));
  78. for(int i=;i<n;i++) A[i]=a[i]&;
  79. for(int i=;i<m;i++) B[i]=b[m-i-]&;
  80. fft(A,nt,);
  81. fft(B,nt,);
  82. for(int i=;i<nt;i++) C[i]=A[i]*B[i];
  83. fft(C,nt,-);
  84. for(int i=;i<n;i++) same[i]+=(int)(C[i].real()+0.5);
  85. for(int i=;i<nt;i++) A[i]=B[i]=C[i]=;
  86. for(int i=;i<n;i++) A[i]=(a[i]&)^;
  87. for(int i=;i<m;i++) B[i]=(b[m-i-]&)^;
  88. fft(A,nt,);
  89. fft(B,nt,);
  90. for(int i=;i<nt;i++) C[i]=A[i]*B[i];
  91. fft(C,nt,-);
  92. for(int i=;i<n;i++) same[i]+=(int)(C[i].real()+0.5);
  93. int ansv=0x3f3f3f3f,anst=;
  94. for(int i=;i<n;i++){
  95. if(!match[i]) continue;
  96. if(m-same[i+m-]<ansv){
  97. ansv=m-same[i+m-];
  98. anst=i+;
  99. }
  100. }
  101. printf("%d %d\n",ansv,anst);
  102. return ;
  103. }

URAL 1996 Cipher Message 3的更多相关文章

  1. URAL 1996 Cipher Message 3 (FFT + KMP)

    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 题意 :给出两个串A , B,每个串是若干个byt ...

  2. Ural 1996 Cipher Message 3 (生成函数+FFT)

    题面传送门 题目大意:给你两个$01$串$a$和$b$,每$8$个字符为$1$组,每组的最后一个字符可以在$01$之间转换,求$b$成为$a$的一个子串所需的最少转换次数,以及此时是从哪开始匹配的. ...

  3. URAL 1996. Cipher Message 3(KMP+fft)

    传送门 解题思路 因为要完全匹配,所以前七位必须保证相同,那么就可以把前7位提出来做一遍\(kmp\)匹配,最后的答案一定在这些位置里.考虑最后一位,可以把最后一位单独取出来,要计算的是最后一位相同的 ...

  4. URAL 1654 Cipher Message 解题报告

    题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1654 题意:简单的理解就是,把一个序列中相邻的且是偶数个相同的字符删除,奇数个的话就只保 ...

  5. ural Cipher Message

    Cipher Message Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Desc ...

  6. URAL1996 Cipher Message 3(KMP + FFT)

    题目 Source http://acm.timus.ru/problem.aspx?space=1&num=1996 Description Emperor Palpatine has be ...

  7. Gym 100285G Cipher Message 3

    题意 给\(N,M(N,M \le 250000)\)的两个由8位二进制表示的两个序列,允许改变每个数字的第8位的数值(即0→1,1→0),求改变最少次数使得长为\(M\)的序列为长为\(N\)的连续 ...

  8. Cipher Message

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=34121#problem/C // File Name: c.cpp // Author: ...

  9. URAL1966 Cipher Message 3

    题目描述 题解: 能看出来的是,每一组数只能改最后一位,所以前$7$位动不了. 所以$KMP$跑一跑. 重点在于最后一位怎么搞. 如果$KMP$跑完了还没找到合适的位置,直接$puts("N ...

随机推荐

  1. git 操作远程仓库地址

    查看所有远程仓库地址: git remote -v 更改远程仓库地址: git remote set-url origin newUrl 查看某一个远程仓库地址: git remote get-url ...

  2. 在eclipse中查找指定文件 [多种方法]

    在eclipse中查找指定文件   1.ctrl+h打开搜索界面 File Search: containing text填*,File name patterns填写hello.*,可以找到hell ...

  3. MacBook Pro使用初体验之Mac快捷键汇总(持续更新中)

    我于近日购置了一台13寸的MacBook Pro高配,打算開始进行iOS开发的学习.Pro的配置情况例如以下: (1)OS X Yosemite ,版本号10.10.3 (2)Retina显示屏,13 ...

  4. linux下如何安装软件(转载)

    来源:http://zhidao.baidu.com/link?url=5oR8WxygPvVMhSZvXQahYKm01JPTmQnEUjbQF562Yxgd3r6bYpki1ZPcHAsij6E4 ...

  5. ASP.NET车辆管理系统100%源代码

    系统开发环境为VS2010.採用ASP.NET框架.数据库採用SQL Server.系统採用Ajax,具有:GPS导航(实时监控报警).申请审核.流程查看及短信息发送等功能.这个系统界面和功能是我认为 ...

  6. ideal 控制台乱码 解决

    run config  中 tomcat VM options中填入一下命令 -Dfile.encoding=UTF-8

  7. leetcode 790. Domino and Tromino Tiling

    We have two types of tiles: a 2x1 domino shape, and an "L" tromino shape. These shapes may ...

  8. java多线程-多线程常识

    线程和进程的区别是什么?进程是一个正在运行的软件程序,打开资源管理器可以看到好多正在运行的进程,而线程则是程序中的顺序控制流,只能使用分配给程序的资源和环境.一个进程至少存在一个线程(主线程). 在j ...

  9. BZOJ 1624 [Usaco2008 Open] Clear And Present Danger 寻宝之路:floyd

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1624 题意: 农夫约翰正驾驶一条小艇在牛勒比海上航行. 海上有N(1≤N≤100)个岛屿, ...

  10. laravel基础课程---2、Laravel配置文件、路由及php artisan(php artisan是什么)

    laravel基础课程---2.Laravel配置文件.路由及php artisan(php artisan是什么) 一.总结 一句话总结: PHP工具匠:php artisan,其实本身就是一些PH ...