URAL 1996 Cipher Message 3 FFT KMP
来源:互联网 发布:淘宝内部优惠券采集 编辑:程序博客网 时间:2024/06/02 19:41
首先还是要回到卷积的定义上
这题这种做法我是看了题解之后才知道的。
如果a是
要利用这个性质,分两步计算。
1. a结尾若是1,b结尾若是0,则ax,bx即做FFT的对应位置权值是1,这样求出的是a为1,b为0的矛盾位数。
2. a结尾若是0,b结尾若是1,则ax,bx即做FFT的对应位置权值是1,这样求出的是a为0,b为1的矛盾位数。
因此这两步做完就能判断矛盾的位数。
最后还要做一个KMP来判断前面七位是否满足。
#include <iostream>#include <algorithm>#include <cstring>#include <cstdio>#include <cmath>using namespace std;const int MAXN = 524288+1000;const int INF = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);struct cp{ double x,y; cp() {} cp(double x,double y):x(x),y(y) {} inline double real() { return x; } inline cp operator * (const cp& r) const { return cp(x*r.x-y*r.y, x*r.y+y*r.x); } inline cp operator - (const cp& r) const { return cp(x-r.x,y-r.y); } inline cp operator + (const cp& r) const { return cp(x+r.x,y+r.y); }};cp a[MAXN],b[MAXN];int r[MAXN],res[MAXN],ax[MAXN],bx[MAXN],n,m;int s1[MAXN],s2[MAXN];void fft_init(int nm,int k){ for (int i=0; i<nm; i++) r[i]= (r[i>>1]>>1) | ((i&1) << (k-1));}void fft(cp ax[],int nm,int op){ for (int i=0; i<nm; i++) if (i<r[i]) swap(ax[i],ax[r[i]]); for (int h=2,m=1; h<=nm; h<<=1,m<<=1) { cp wn = cp(cos(op*2*pi/h),sin(op*2*pi/h)); for (int i=0; i<nm; i+=h) { cp w(1,0); for (int j=i; j<i+m; j++,w=w*wn) { cp t=w*ax[j+m]; ax[j+m] = ax[j]-t; ax[j] = ax[j]+t; } } } if (op==-1) for (int i=0; i<nm; i++) ax[i].x /= nm;}void trans(int n,int m,int x,int y){ int nm=1,k=0; while (nm < 2*n || nm <2*m ) nm<<=1,++k; for (int i=0; i<n; i++) { if ((s1[i]&1) == x) ax[i] = 1; else ax[i] = 0; } for (int i=0; i<m; i++) { if ((s2[m-i-1]&1) == y) bx[i] = 1; else bx[i] = 0; } for (int i=0; i<n; i++) a[i] = cp(ax[i],0); for (int i=0; i<m; i++) b[i] = cp(bx[i],0); for (int i=n; i<nm; i++) a[i] = cp(0,0); for (int i=m; i<nm; i++) b[i] = cp(0,0); fft_init(nm,k); fft(a,nm,1); fft(b,nm,1); for (int i=0; i<nm; i++) a[i] = a[i] * b[i]; fft(a,nm,-1); nm = n+m-1; for (int i=0; i<nm; i++) res[i] += (int)(a[i].real() + 0.5);}int nex[MAXN];void getnext(int m){ int j=0; for (int i=1;i<m;i++) { while (j && s2[i]!=s2[j]) j=nex[j]; if (s2[i]==s2[j]) j++; nex[i+1]=j; }}void KMP_Count(int n,int m){ int ans=INF,pos=0; for (int i=0,j=0;i<n;i++) { while(j && s1[i]!=s2[j]) j=nex[j]; if (s1[i] == s2[j]) { j++; if(j==m) { if (ans > res[i]) { ans = res[i]; pos = i-m+1; } j=nex[j]; } } else j=nex[j]; } if (ans == INF) printf("No\n"); else { printf("Yes\n"); printf("%d %d\n",ans,pos+1); }}int main(){ while (scanf("%d%d",&n,&m)!=EOF) { memset(res,0,sizeof res); for (int i=0; i<n; i++) scanf("%d",&s1[i]); for (int i=0; i<m; i++) scanf("%d",&s2[i]); trans(n,m,1,0); trans(n,m,0,1); for (int i=0;i<n;i++) s1[i]/=10; for (int i=0;i<m;i++) s2[i]/=10; getnext(m); KMP_Count(n,m); } return 0;}
阅读全文
0 0
- URAL 1996 Cipher Message 3 (FFT + KMP)
- URAL 1996 Cipher Message 3 FFT + KMP
- URAL 1996 Cipher Message 3 (FFT + KMP)
- URAL 1996 Cipher Message 3 FFT KMP
- ural 1996. Cipher Message 3 KMP+FFT
- 【ural】1996. Cipher Message 3【FFT+KMP】
- ural 1654 Cipher Message
- URAL 1654 - Cipher Message
- ural 1654. Cipher Message
- Ural 1654 Cipher Message
- Ural 1654. Cipher Message
- Ural 1654. Cipher Message
- URAL 1654 Cipher Message
- ural 1654. Cipher Message
- URAL 1654 Cipher Message(栈)
- Ural 1706. Cipher Message 2 后缀数组
- URAL 1654. Cipher Message (STL stack)
- Cipher Message
- 01Redis学习
- lintcode Guess Number Game II
- 【福分系统】bootstrap表格控件
- jquery实现品牌列表的显示
- 自定义bs soup的抓取函数,查找不含某个class属性tag 以及一个小问题'NoneType' object has no attribute '__getitem__'
- URAL 1996 Cipher Message 3 FFT KMP
- leetcode200. Number of Islands
- 在maven项目中使用Junit的assertThat()方法时,is()方法的使用
- Linux之Shell基础
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 J Minimum Distance in a Star Graph 广度优先搜索
- xtu 8
- bzoj 4590: [Shoi2015]自动刷题机
- kibana安装使用
- jquery实现全选 全不选效果