题面传送门

题目大意:给你两个$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. [bzoj3123][Sdoi2013]森林_主席树_启发式合并

    森林 bzoj-3123 Sdoi-2013 题目大意:给定一片共n个点的森林,T个操作,支持:连接两个不在一棵树上的两个点:查询一棵树上路径k小值. 注释:$1\le n,T \le 8\cdot ...

  2. Spring bean生命周期(一)

    当容器销毁的时候,先调用DisposableBean实现类的destroy()方法,在调destory-method方法.

  3. 百度2016研发project师笔试题(四)

    百度2016研发project师笔试题(四) 2015/12/8 10:42(网上收集整理的,參考答案在后面.若有错误请大神指出) 1. 关于MapReduce的描写叙述错误的是() A. 一个Tas ...

  4. root用户不能改动iptables

    需求:因为防火墙做了IP和port限制,如今须要加入一条规则使之能够訪问指定的IP和port. vi /etc/sysconfig/iptables, 加入完毕后,wq保存,提示文件仅仅读无法保存.! ...

  5. Git与SVN区别 \git学习

    http://blog.csdn.net/w13770269691/article/details/38705473/ https://git-scm.com/book/zh/v2

  6. C++一些知识难点

    什么是"引用"?申明和使用"引用"要注意哪些问题? 答:引用就是某个目标变量的"别名"(alias).相应用的操作与对变量直接操作效果全然同 ...

  7. Android下添加新的自定义键值和按键处理流程【转】

    本文转载自: Android下添加新的自定义键值和按键处理流程     说出来不怕大家笑话,我写这篇博客的原因在于前几天去一个小公司面试Android系统工程师,然后在面试的时候对方的技术总监问了我一 ...

  8. bzoj5029: 贴小广告&&bzoj5168: [HAOI2014]贴海报

    以后做双精题请至少先跑个数据...输入都不一样... 做法就是离散化大力线段树. 记得在x+1和y-1插点 看这个数据: 1000 121 10050 8080 9950 981 56100 2002 ...

  9. Dungeon Master hdoj

    Dungeon Master Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other) Tot ...

  10. 杂项-DB:OLAP(联机分析处理)

    ylbtech-杂项-DB:OLAP(联机分析处理) 联机分析处理OLAP是一种软件技术,它使分析人员能够迅速.一致.交互地从各个方面观察信息,以达到深入理解数据的目的.它具有FASMI(Fast A ...