题面传送门

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

FFT怎么变成字符串算法了

每组的前$7$个字符是不能动的,所以把它压成一个数,用$kmp$求出$b$可能作为$a$子串的所有结束位置

求最少的转换次数呢,把$a,b$串每一组的最后一位取出来分别组成新串,再把$b$的新串反转求卷积即可

反转$b$串的目的是,让答案出现在同一个系数里,算是$FFT$进行字符串匹配的一个经典套路

 #include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N1 (1<<19)
#define M1 (N1<<1)
#define il inline
#define dd double
#define ld long double
#define ll long long
using namespace std; int gint()
{
int ret=,fh=;char c=getchar();
while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
while(c>=''&&c<=''){ret=ret*+c-'';c=getchar();}
return ret*fh;
} const int inf=0x3f3f3f3f;
namespace FFT{ const dd pi=acos(-);
struct cp{
dd x,y;
friend cp operator + (const cp &s1,const cp &s2){ return (cp){s1.x+s2.x,s1.y+s2.y}; }
friend cp operator - (const cp &s1,const cp &s2){ return (cp){s1.x-s2.x,s1.y-s2.y}; }
friend cp operator * (const cp &s1,const cp &s2){ return (cp){s1.x*s2.x-s1.y*s2.y,s1.y*s2.x+s1.x*s2.y}; }
}a[N1],b[N1],c[N1];
int r[N1];
void FFT(cp *s,int len,int type)
{
int i,j,k; cp wn,w,t;
for(i=;i<len;i++) if(i<r[i]) swap(s[i],s[r[i]]);
for(k=;k<=len;k<<=)
{
wn=(cp){cos(2.0*type*pi/k),sin(2.0*type*pi/k)};
for(i=;i<len;i+=k)
{
w=(cp){,};
for(j=;j<(k>>);j++,w=w*wn)
{
t=w*s[i+j+(k>>)];
s[i+j+(k>>)]=s[i+j]-t;
s[i+j]=s[i+j]+t;
}
}
}
}
void FFT_Main(int len)
{
int i;
FFT(a,len,); FFT(b,len,);
for(i=;i<len;i++) c[i]=a[i]*b[i];
FFT(c,len,-);
for(i=;i<len;i++) c[i].x/=len;
}
void init()
{
memset(a,,sizeof(a));
memset(b,,sizeof(b));
} }; int a[N1],b[N1],A[N1],B[N1],nxt[N1],ans[N1],num[N1];
void get_nxt(int len)
{
int i=,j=-; nxt[]=-;
while(i<len)
{
if(j==-||b[i]==b[j]){ i++; j++; nxt[i]=j; }
else { j=nxt[j]; }
}
}
void KMP(int len)
{
int i=,j=;
while(i<len)
{
if(j==-||a[i]==b[j]){ i++; j++; ans[i]=j; }
else{ j=nxt[j]; }
}
} int T,n,m; int main()
{ scanf("%d%d",&n,&m);
int i,j,s,ret=inf,id,len,L; char str[];
memset(a,-,sizeof(a)); memset(b,-,sizeof(b));
for(i=;i<n;i++)
{
scanf("%s",str);
for(j=,s=;j<;j++) s=(s<<)+str[j]-'';
a[i]=s; A[i]=str[]-'';
}
for(i=;i<m;i++)
{
scanf("%s",str);
for(j=,s=;j<;j++) s=(s<<)+str[j]-'';
b[i]=s; B[m-i-]=str[]-'';
}
for(len=,L=;len<n+m-;len<<=,L++);
for(i=;i<len;i++) FFT::r[i]=(FFT::r[i>>]>>)|((i&)<<(L-)); for(i=;i<n;i++) FFT::a[i].x=(A[i]==)?:;
for(i=;i<m;i++) FFT::b[i].x=(B[i]==)?:;
FFT::FFT_Main(len);
for(i=;i<len;i++) num[i]+=(int)(FFT::c[i].x+0.1); FFT::init();
for(i=;i<n;i++) FFT::a[i].x=(A[i]==)?:;
for(i=;i<m;i++) FFT::b[i].x=(B[i]==)?:;
FFT::FFT_Main(len);
for(i=;i<len;i++) num[i]+=(int)(FFT::c[i].x+0.1); get_nxt(m); KMP(n);
for(i=m;i<=n;i++)
{
if(ans[i]<m) continue;
if(m-num[i-]<ret){ id=i-m+; ret=m-num[i-]; }
}
if(ret==inf) puts("No");
else{ puts("Yes"); printf("%d %d\n",ret,id); } return ; }

Ural 1996 Cipher Message 3 (生成函数+FFT)的更多相关文章

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

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

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

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

  3. URAL 1996 Cipher Message 3

    题目 神题. 记得当初DYF和HZA讲过一个FFT+KMP的题目,一直觉得很神,从来没去做. 没有真正理解FFT的卷积. 首先考虑暴力. 只考虑前7位 KMP 找出所有 B 串可以匹配 A 串的位置. ...

  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. loj6570 毛毛虫计数(生成函数FFT)

    link 巨佬olinr的题解 <-- olinr很强 考虑生成函数 考虑直径上点数>=4的毛毛虫的直径,考虑直径中间那些节点以及他上面挂的那些点的EGF \(A(x)=\sum_{i\g ...

  7. URAL1996 Cipher Message 3(KMP + FFT)

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

  8. 挑选队友 (生成函数 + FFT + 分治)

    链接:https://www.nowcoder.com/acm/contest/133/D来源:牛客网 题目描述 Applese打开了m个QQ群,向群友们发出了组队的邀请.作为网红选手,Applese ...

  9. 【BZOJ3771】Triple 生成函数 FFT 容斥原理

    题目大意 有\(n\)把斧头,不同斧头的价值都不同且都是\([0,m]\)的整数.你可以选\(1\)~\(3\)把斧头,总价值为这三把斧头的价值之和.请你对于每种可能的总价值,求出有多少种选择方案. ...

随机推荐

  1. 大红数星星 图论 XD网络赛

    问题 A: 大红数星星 时间限制: 3 Sec  内存限制: 128 MB提交: 1066  解决: 67[提交][状态][讨论版] 题目描述 “三角形十分的美丽,相信大家小学就学过三角形具有稳定性, ...

  2. Mysql查询缓存研究

    转载声明:本文为DBA+社群原创文章,转载必须连同本订阅号二维码全文转载,并注明作者名字及来源:DBA+社群(dbaplus). http://mp.weixin.qq.com/s?__biz=MzI ...

  3. Netty In Action中文版 - 第十五章:选择正确的线程模型

    http://blog.csdn.net/abc_key/article/details/38419469 本章介绍 线程模型(thread-model) 事件循环(EventLoop) 并发(Con ...

  4. 【JavaScript】在同一个网页中实现多个JavaScript特效

    在网页中,假设出现两次<script type="text/javascript"></script>标签,全部的JavaScipt脚本都不会再生效,仅仅能 ...

  5. 【视频】零基础学Android开发:蓝牙聊天室APP(一)

    零基础学Android开发:蓝牙聊天室APP第一讲 1. Android介绍与环境搭建:史上最高效Android入门学习 1.1 Google的大小战略 1.2 物联网与云计算 1.3 智能XX设备 ...

  6. 学习 java netty (一) -- java nio

    前言:近期在研究java netty这个网络框架,第一篇先介绍java的nio. java nio在jdk1.4引入,事实上也算比較早的了.主要引入非堵塞io和io多路复用.内部基于reactor模式 ...

  7. Warning: File `src/core/nginx.h&#39; has modification time 1.2e+07 s in the future

    Nginx安装时Warning: File `src/core/nginx.h' has modification time 1.2e+07 s in the future问题的解决方法 问题场景: ...

  8. open Command window here

    http://www.sevenforums.com/tutorials/134831-open-command-window-here-add-remove.html 按照教程里面,下载一个脚本 需 ...

  9. DNS tunnel的原理及实战

    DNS tunnel的原理及实战 摘自:http://netsec.ccert.edu.cn/zhengming/2011/11/01/%E8%BD%AC%E8%BD%BD%EF%BC%9Adns-t ...

  10. Node.js:Buffer

    ylbtech-Node.js:Buffer 1.返回顶部 1. Node.js Buffer(缓冲区) JavaScript 语言自身只有字符串数据类型,没有二进制数据类型. 但在处理像TCP流或文 ...