记录编号 414146 评测结果 AAAAAAAAAAA
题目名称 [BZOJ 4503] 你猜是不是KMP 最终得分 100
用户昵称 Gravatar_Itachi 是否通过 通过
代码语言 C++ 运行时间 0.973 s
提交时间 2017-06-13 15:40:28 内存使用 14.79 MiB
显示代码纯文本
  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<algorithm>
  4. #include<math.h>
  5. using namespace std;
  6. const int maxn=1<<18|7;
  7. const double Pi=acos(-1.0);
  8. struct Vec {
  9. double x,y;
  10. Vec operator + (const Vec &a){return (Vec){x+a.x,y+a.y};}
  11. Vec operator - (const Vec &a){return (Vec){x-a.x,y-a.y};}
  12. Vec operator * (const Vec &a){return (Vec){x*a.x-y*a.y,x*a.y+y*a.x};}
  13. Vec operator * (const double &a){return (Vec){x*a,y*a};}
  14. Vec Get(bool b){return (Vec){x,b?-y:y};}
  15. }c[maxn],c1[maxn],w[maxn];int rev[maxn],n,Fu;double Inv;
  16. void FFt(int N){
  17. int len=0,i;n=1;
  18. while(n<N)n<<=1,len++;len--;Fu=n-1,Inv=1./n;
  19. for(i=0;i<n;i++)
  20. rev[i]=rev[i>>1]>>1|((i&1)<<len),
  21. w[i]=(Vec){cos(2*Pi/n*i),sin(2*Pi/n*i)};
  22. }
  23. void FFt(Vec *a,bool op){
  24. int i,j,k;Vec t;
  25. for(i=0;i<n;i++)if(i<rev[i])swap(a[i],a[rev[i]]);
  26. for(k=2;k<=n;k<<=1)
  27. for(j=0;j<n;j+=k)
  28. for(i=0;i<(k>>1);i++)
  29. t=a[i+j+(k>>1)]*w[n/k*i].Get(op),a[i+j+(k>>1)]=a[i+j]-t,a[i+j]=a[i+j]+t;
  30. if(op)for(i=0;i<n;i++)a[i]=a[i]*Inv;
  31. }
  32. int len1,len2,cot=0,st[maxn];char S[maxn],T[maxn];
  33. int main(){
  34. freopen("guess.in","r",stdin);freopen("guess.out","w",stdout);
  35. scanf("%s%s",S,T);len2=strlen(S),len1=strlen(T);
  36. FFt(len2+len1);reverse(T,T+len1);int i,j,t3=0;
  37. for(i=0;i<len2;i++)S[i]-='a'-1;
  38. for(i=0;i<len1;i++){
  39. if(T[i]=='?')T[i]=0;else T[i]-='a'-1;
  40. t3+=T[i]*T[i]*T[i];
  41. }
  42. for(i=0;i<n;i++)c[i]=(Vec){S[i]*S[i],T[i]};
  43. FFt(c,0);Vec v=(Vec){0.5,0}*(Vec){0,-0.5};
  44. for(i=0;i<n;i++)
  45. j=(n-i)&Fu,c1[i]=(c[i]+c[j].Get(1))*(c[i]-c[j].Get(1))*v;
  46. for(i=0;i<n;i++)c[i]=(Vec){S[i],T[i]*T[i]};
  47. FFt(c,0);v=v*2;
  48. for(i=0;i<n;i++)
  49. j=(n-i)&Fu,c1[i]=c1[i]-((c[i]+c[j].Get(1))*(c[i]-c[j].Get(1))*v);
  50. FFt(c1,1);
  51. for(i=0;i+len1<=len2;i++)if(t3+round(c1[i+len1-1].x)==0)st[++cot]=i;
  52. printf("%d\n",cot);
  53. for(i=1;i<=cot;i++)printf("%d\n",st[i]);
  54. }