zoukankan      html  css  js  c++  java
  • 【BZOJ4503】两个串 FFT

    【BZOJ4503】两个串

    Description

    兔子们在玩两个串的游戏。给定两个字符串S和T,兔子们想知道T在S中出现了几次,
    分别在哪些位置出现。注意T中可能有“?”字符,这个字符可以匹配任何字符。

    Input

    两行两个字符串,分别代表S和T

    Output

    第一行一个正整数k,表示T在S中出现了几次
    接下来k行正整数,分别代表T每次在S中出现的开始位置。按照从小到大的顺序输出,S下标从0开始。

    Sample Input

    bbabaababaaaaabaaaaaaaabaaabbbabaaabbabaabbbbabbbbbbabbaabbbababababbbbbbaaabaaabbbbbaabbbaabbbbabab
    a?aba?abba

    Sample Output

    0

    HINT

    S 长度不超过 10^5, T 长度不会超过 S。 S 中只包含小写字母, T中只包含小写字母和“?”

    题解:同【BZOJ4259】残缺的字符串

    不过这里不需要外面在乘一个Si+j,所以少了一项,直接计算出来就行

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <cmath>
    #define pi acos(-1.0)
    using namespace std;
    struct cp
    {
    	double x,y;
    	cp (double a,double b){x=a,y=b;}
    	cp (){}
    	cp operator + (cp a){return cp(x+a.x,y+a.y);}
    	cp operator - (cp a){return cp(x-a.x,y-a.y);}
    	cp operator * (cp a){return cp(x*a.x-y*a.y,x*a.y+y*a.x);}
    }n1[1<<20],n2[1<<20],n3[1<<20],n4[1<<20];
    int s[1<<20],t[1<<20];
    int ans[1<<20],sta[1<<20];
    int l1,l2,top,n5;
    char s1[1<<20],s2[1<<20];
    void FFT(cp *a,int len,int f)
    {
    	int i,j,k,h;
    	cp t;
    	for(i=k=0;i<len;i++)
    	{
    		if(i>k)	swap(a[i],a[k]);
    		for(j=(len>>1);(k^=j)<j;j>>=1);
    	}
    	for(h=2;h<=len;h<<=1)
    	{
    		cp wn(cos(f*2*pi/h),sin(f*2*pi/h));
    		for(j=0;j<len;j+=h)
    		{
    			cp w(1,0);
    			for(k=j;k<j+h/2;k++)	t=w*a[k+h/2],a[k+h/2]=a[k]-t,a[k]=a[k]+t,w=w*wn;
    		}
    	}
    }
    int main()
    {
    	int i,j,len=1;
    	scanf("%s%s",s1,s2),l1=strlen(s1),l2=strlen(s2);
    	while(len<l1+2*l2)	len<<=1;
    	for(i=0;i<l1;i++)	s[i]=s1[i]-'a'+1;
    	for(i=0;i<l2;i++)	t[l2-i-1]=(s2[i]=='?')?0:(s2[i]-'a'+1);
    	for(i=0;i<l1;i++)	n1[i]=cp(1.0*s[i]*s[i],0.0),n3[i]=cp(2.0*s[i],0.0);
    	for(i=0;i<l2;i++)	n2[i]=cp(1.0*t[i],0.0),n4[i]=cp(1.0*t[i]*t[i],0.0);
    	FFT(n1,len,1),FFT(n2,len,1),FFT(n3,len,1),FFT(n4,len,1);
    	for(i=0;i<len;i++)	n1[i]=n1[i]*n2[i]-n3[i]*n4[i];
    	FFT(n1,len,-1);
    	for(i=0;i<l2;i++)	n5+=t[i]*t[i]*t[i];
    	for(i=0;i<l1-l2+1;i++)	if(!(int)(n1[i+l2-1].x/len+n5+0.5))	sta[++top]=i;
    	printf("%d
    ",top);
    	for(i=1;i<=top;i++)	printf("%d
    ",sta[i]);
    	return 0;
    }
  • 相关阅读:
    ArcEngine中删除地物点(C#)
    Siliverlight常识
    ArcEngine 中打开数据源的连接 AO学习资料笔记
    第一次执行时没有问题,重复执行会出错、GP循环
    理解 ArcObjects 中的游标
    AO 中关于坐标系统的感想 AO学习资料 阅读
    http://www.chinabzw.com/bzlist/7_1.htm
    Delphi 文件操作(4)Reset
    c 语言指针
    Delphi 获取星期几
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/6878681.html
Copyright © 2011-2022 走看看