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 ...
随机推荐
- iOS 摇一摇的实现
- (void)viewDidLoad { [super viewDidLoad]; [[UIApplication sharedApplication] setApplicationSupports ...
- AMD单双桥时序简叙
芯片组(双桥)时序 VBAT :RTC电路的供电3V(RTC电路有问题会导致没复位或不跑码等故障) RTCCLK :晶振起振给南桥提供32.768KHz频率(RTC电路有问题会导致没复位或不跑码等故障 ...
- upstart man
man upstart nit(8) init(8) NAME init - Upstart process management daemon SYNOPSIS init [OPTION]... D ...
- Kubernetes基本概念之Label
系列目录 在为对象定义好Label后,其他对象就可以通过Label来对对象进行引用.Label的最常见的用法便是通过spec.selector来引用对象. apiVersion: v1 kind: R ...
- Java中Class.forName()的作用(转载)
http://www.360doc.com/content/10/0712/10/1720440_38421273.shtml# 使用jdbc方式连接数据库时会使用一句代码Class.forName( ...
- 学习某些API的方法
学习某些 API 的方法 这里的 API 可能是某个系统平台,开发包,开发平台,开发工具等等,因为任何系统和技术方法提供给开发者的打包方式都是一系列 API . 无论你有在哪一层级开发,从硬件驱动到系 ...
- android:PopupWindow的使用场景和注意事项
1.PopupWindow的特点 借用Google官方的说法: "A popup window that can be used to display an arbitrary view. ...
- Linux中ctrl+z 、ctrl+c、 ctrl+d差别
ctrl+c,ctrl+d,ctrl+z在linux程序中意义和差别 ctrl+c和ctrl+z都是中断命令,可是他们的作用却不一样. ctrl+c是强制中断程序的运行,,进程已经终止. ct ...
- ffmpeg ffplay播放延时大问题:播放延时参数设置
使用ffplay播放视频源时,rtsp/rtmp等,会有一定的延时,这里我们可以通过设置ffplay播放参数将延时控制到最小. ffplay.exe -i rtmp://xxxxxxx -fflags ...
- 九度OJ 1136:Number Steps(步数) (基础题)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:691 解决:412 题目描述: Starting from point (0,0) on a plane, we have written ...