URAL 1996 Cipher Message 3
神题。
记得当初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解决。
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- #include <complex>
- #include <cmath>
- #define N 250010
- #define Ex complex<double>
- #define pi 3.14159265354
- using namespace std;
- int n,m,a[N],b[N],same[N],rev[N<<];
- inline void scan(int &x){
- char tmp[];
- scanf("%s",tmp);
- x=;
- int len=strlen(tmp);
- for(int i=len-;~i;i--)
- if(tmp[i]=='') x|=(<<(len-i-));
- }
- inline bool simple(int a,int b){
- return (a|)==(b|);
- }
- int f[N];
- bool match[N];
- Ex A[N<<],B[N<<],C[N<<];
- void fft(Ex x[],int n,int t){
- for(int i=;i<n;i++){
- if(rev[i]>i) swap(x[rev[i]],x[i]);
- }
- for(int m=;m<n;m<<=){
- Ex wn(cos(pi/m*t),sin(pi/m*t));
- for(int k=;k<n;k+=(m<<)){
- Ex wt(,);
- for(int i=;i<m;i++,wt*=wn){
- Ex &A=x[i+m+k],&B=x[i+k],tmp=wt*A;
- A=B-tmp; B=B+tmp;
- }
- }
- }
- if(t==-){
- for(int i=;i<n;i++)
- x[i]/=(double)n;
- }
- }
- int main(){
- freopen("message10.in","r",stdin);
- scanf("%d%d",&n,&m);
- for(int i=;i<n;i++) scan(a[i]);
- for(int i=;i<m;i++) scan(b[i]);
- f[]=f[]=;
- for(int i=;i<m;i++){
- int j=f[i];
- while(j&&!simple(b[i],b[j])) j=f[j];
- f[i+]= simple(b[i],b[j])? j+:;
- }
- int j=;
- bool flag=;
- for(int i=;i<n;i++){
- while(j&&!simple(b[j],a[i])) j=f[j];
- if(simple(b[j],a[i])) j++;
- if(j==m) match[i-m+]=,flag=;
- }
- if(!flag){
- puts("No");
- return ;
- }
- puts("Yes");
- int T=,nt;
- for(nt=;nt<=(n+m);nt<<=) T++;
- for(int i=;i<nt;i++) rev[i]=(rev[i>>]>>)|((i&)<<(T-));
- for(int i=;i<n;i++) A[i]=a[i]&;
- for(int i=;i<m;i++) B[i]=b[m-i-]&;
- fft(A,nt,);
- fft(B,nt,);
- for(int i=;i<nt;i++) C[i]=A[i]*B[i];
- fft(C,nt,-);
- for(int i=;i<n;i++) same[i]+=(int)(C[i].real()+0.5);
- for(int i=;i<nt;i++) A[i]=B[i]=C[i]=;
- for(int i=;i<n;i++) A[i]=(a[i]&)^;
- for(int i=;i<m;i++) B[i]=(b[m-i-]&)^;
- fft(A,nt,);
- fft(B,nt,);
- for(int i=;i<nt;i++) C[i]=A[i]*B[i];
- fft(C,nt,-);
- for(int i=;i<n;i++) same[i]+=(int)(C[i].real()+0.5);
- int ansv=0x3f3f3f3f,anst=;
- for(int i=;i<n;i++){
- if(!match[i]) continue;
- if(m-same[i+m-]<ansv){
- ansv=m-same[i+m-];
- anst=i+;
- }
- }
- printf("%d %d\n",ansv,anst);
- return ;
- }
URAL 1996 Cipher Message 3的更多相关文章
- URAL 1996 Cipher Message 3 (FFT + KMP)
转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove 题意 :给出两个串A , B,每个串是若干个byt ...
- Ural 1996 Cipher Message 3 (生成函数+FFT)
题面传送门 题目大意:给你两个$01$串$a$和$b$,每$8$个字符为$1$组,每组的最后一个字符可以在$01$之间转换,求$b$成为$a$的一个子串所需的最少转换次数,以及此时是从哪开始匹配的. ...
- URAL 1996. Cipher Message 3(KMP+fft)
传送门 解题思路 因为要完全匹配,所以前七位必须保证相同,那么就可以把前7位提出来做一遍\(kmp\)匹配,最后的答案一定在这些位置里.考虑最后一位,可以把最后一位单独取出来,要计算的是最后一位相同的 ...
- URAL 1654 Cipher Message 解题报告
题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1654 题意:简单的理解就是,把一个序列中相邻的且是偶数个相同的字符删除,奇数个的话就只保 ...
- ural Cipher Message
Cipher Message Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Desc ...
- URAL1996 Cipher Message 3(KMP + FFT)
题目 Source http://acm.timus.ru/problem.aspx?space=1&num=1996 Description Emperor Palpatine has be ...
- Gym 100285G Cipher Message 3
题意 给\(N,M(N,M \le 250000)\)的两个由8位二进制表示的两个序列,允许改变每个数字的第8位的数值(即0→1,1→0),求改变最少次数使得长为\(M\)的序列为长为\(N\)的连续 ...
- Cipher Message
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=34121#problem/C // File Name: c.cpp // Author: ...
- URAL1966 Cipher Message 3
题目描述 题解: 能看出来的是,每一组数只能改最后一位,所以前$7$位动不了. 所以$KMP$跑一跑. 重点在于最后一位怎么搞. 如果$KMP$跑完了还没找到合适的位置,直接$puts("N ...
随机推荐
- git 操作远程仓库地址
查看所有远程仓库地址: git remote -v 更改远程仓库地址: git remote set-url origin newUrl 查看某一个远程仓库地址: git remote get-url ...
- 在eclipse中查找指定文件 [多种方法]
在eclipse中查找指定文件 1.ctrl+h打开搜索界面 File Search: containing text填*,File name patterns填写hello.*,可以找到hell ...
- MacBook Pro使用初体验之Mac快捷键汇总(持续更新中)
我于近日购置了一台13寸的MacBook Pro高配,打算開始进行iOS开发的学习.Pro的配置情况例如以下: (1)OS X Yosemite ,版本号10.10.3 (2)Retina显示屏,13 ...
- linux下如何安装软件(转载)
来源:http://zhidao.baidu.com/link?url=5oR8WxygPvVMhSZvXQahYKm01JPTmQnEUjbQF562Yxgd3r6bYpki1ZPcHAsij6E4 ...
- ASP.NET车辆管理系统100%源代码
系统开发环境为VS2010.採用ASP.NET框架.数据库採用SQL Server.系统採用Ajax,具有:GPS导航(实时监控报警).申请审核.流程查看及短信息发送等功能.这个系统界面和功能是我认为 ...
- ideal 控制台乱码 解决
run config 中 tomcat VM options中填入一下命令 -Dfile.encoding=UTF-8
- leetcode 790. Domino and Tromino Tiling
We have two types of tiles: a 2x1 domino shape, and an "L" tromino shape. These shapes may ...
- java多线程-多线程常识
线程和进程的区别是什么?进程是一个正在运行的软件程序,打开资源管理器可以看到好多正在运行的进程,而线程则是程序中的顺序控制流,只能使用分配给程序的资源和环境.一个进程至少存在一个线程(主线程). 在j ...
- BZOJ 1624 [Usaco2008 Open] Clear And Present Danger 寻宝之路:floyd
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1624 题意: 农夫约翰正驾驶一条小艇在牛勒比海上航行. 海上有N(1≤N≤100)个岛屿, ...
- laravel基础课程---2、Laravel配置文件、路由及php artisan(php artisan是什么)
laravel基础课程---2.Laravel配置文件.路由及php artisan(php artisan是什么) 一.总结 一句话总结: PHP工具匠:php artisan,其实本身就是一些PH ...