bzoj 4503 两个串
来源:互联网 发布:网络电信诈骗防 编辑:程序博客网 时间:2024/06/06 18:03
4503: 两个串
Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 580 Solved: 259
[Submit][Status][Discuss]
Description
兔子们在玩两个串的游戏。给定两个字符串S和T,兔子们想知道T在S中出现了几次,
分别在哪些位置出现。注意T中可能有“?”字符,这个字符可以匹配任何字符。
Input
两行两个字符串,分别代表S和T
Output
第一行一个正整数k,表示T在S中出现了几次
接下来k行正整数,分别代表T每次在S中出现的开始位置。按照从小到大的顺序输出,S下标从0开始。
Sample Input
bbabaababaaaaabaaaaaaaabaaabbbabaaabbabaabbbbabbbbbbabbaabbbababababbbbbbaaabaaabbbbbaabbbaabbbbabab
a?aba?abba
a?aba?abba
Sample Output
0
HINT
S 长度不超过 10^5, T 长度不会超过 S。 S 中只包含小写字母, T中只包含小写字母和“?”
【分析】
hzwer版本的#include<complex>太慢了...换了licone的struct complex 版本,跑起来挺快
FFT这个东西就是要跑脑洞...
这个题应该算是通配符匹配问题中的一类吧
把模式串翻转一下
令 c[j+m-1]=sigama{(a[j+i]-b[m-1-i)^2*b[m-1-i]}
展开以后有三只卷鸡,然后黑箱FFT = =
(还是要多加练习FFT啊...每次根本看不出来qwq)
(其实我现在才知道卷鸡可以带平方三次方什么的...黑箱果然还是不太好)
【代码】
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#define pi acos(-1)#define ll long long#define M(a) memset(a,0,sizeof a)#define fo(i,j,k) for(int i=j;i<=k;i++)using namespace std;const int mxn=400005;char s[mxn];int n,m,L,N,M;int R[mxn],ans[mxn];double pre[mxn],now[mxn];struct E{double r,f; //real & fakeE (double u,double v) {r=u,f=v;}E () {}E operator + (E u) {return E(r+u.r,f+u.f);}E operator - (E u) {return E(r-u.r,f-u.f);}E operator * (E u) {return E(r*u.r-f*u.f,r*u.f+f*u.r);}E operator / (int v) {return E(r/v,f/v);}}a[mxn],b[mxn],c[mxn];inline void fft(E *a,int f){fo(i,0,n-1) if(i<R[i]) swap(a[i],a[R[i]]);for(int i=1;i<n;i<<=1){E wn(cos(pi/i),f*sin(pi/i));for(int j=0;j<n;j+=(i<<1)){E w(1,0);for(int k=0;k<i;k++,w=w*wn){E x=a[j+k],y=w*a[j+k+i];a[j+k]=x+y,a[j+k+i]=x-y;}}}if(f==-1) fo(i,0,n-1) a[i]=a[i]/n;}int main(){ scanf("%s",s);n=strlen(s); fo(i,0,n-1) pre[i]=(double)s[i]-'a'+1; scanf("%s",s);m=strlen(s); fo(i,0,m-1) now[i]=s[m-i-1]=='?'?(double)0:(double)s[m-i-1]-'a'+1; M=2*n;for(n=1;n<M;n<<=1) L++;M/=2; fo(i,0,n-1) R[i]=(R[i>>1]>>1|((i&1)<<L-1)); //a^2*b fo(i,0,M-1) a[i].r=pre[i]*pre[i],b[i].r=now[i]; fft(a,1),fft(b,1); fo(i,0,n-1) c[i]=a[i]*b[i]; fo(i,0,n-1) a[i].r=a[i].f=b[i].r=b[i].f=0; //2*a*b^2 fo(i,0,M-1) a[i].r=pre[i],b[i].r=now[i]*now[i]; fft(a,1),fft(b,1); fo(i,0,n-1) c[i]=c[i]-a[i]*b[i]-a[i]*b[i]; fo(i,0,n-1) a[i].r=a[i].f=b[i].r=b[i].f=0; //b^3 fo(i,0,M-1) a[i].r=(double)1,b[i].r=now[i]*now[i]*now[i];fft(a,1),fft(b,1);fo(i,0,n-1) c[i]=c[i]+a[i]*b[i];fft(c,-1);fo(i,m-1,M-1) if(fabs(c[i].r)<0.5) ans[++ans[0]]=i-m+1;fo(i,0,ans[0]) printf("%d\n",ans[i]); return 0;}
1 0
- 【BZOJ 4503】两个串
- BZOJ 4503 两个串
- BZOJ 4503: 两个串
- bzoj 4503 两个串
- bzoj 4503: 两个串 fft
- bzoj 4503: 两个串 fft
- bzoj 4503: 两个串 (FFT+DP)
- BZOJ 4503: 两个串 FFT 通配符匹配
- [BZOJ]4503 两个串:我的第一次FFT尝试
- 4503: 两个串 FFT
- bzoj 2740: 串
- bzoj-3676 回文串
- [BZOJ 2946]公共串
- BZOJ 3676 回文串
- [BZOJ ]
- BZOJ****-****
- BZOJ
- BZOJ
- qml自定义Combobox
- Android 自定义 DialogFragment 宽度问题
- OpenCV中的Image Watch,VS2013像matlab一样方便查看图像Mat像素值等
- javascript 正则表达式 exec /g 死循环
- TCP数据分包
- bzoj 4503 两个串
- Cleanup failed to process the following paths错误的解决
- 原生JavaScript节点
- hdu 1074 Doing Homework(状压dp)
- Android View
- python数据输入caffe实现回归
- C:数组实现十进制转换二进制
- JSON JSONArray 创建JSON 和 解析JSON
- 很好的sql去重