Luo Gu P4173 incomplete string

Subject to the effect:

Two with wildcard character string \ (A, B \) , find \ (A \) in \ (B \) position appears

String length \ (\ le 300000 \)

Consider the devil to change the situation as \ (kmp \) , found that change does not come out of magic

So consider the Internet search solution to a problem

Then consider \ (NTT \) , was found to meet the need to match the two strings \ (\ sum \ limits_ {i = 0} ^ {n-1} (a_i-b_i) = 0 \)

Found not quite right, there may be a destructive equal positive and negative \ (0 \) , we add square \ (\ sum \ limits_ {i = 0} ^ {n-1} (a_i-b_i) ^ 2 = 0 \ )

Consider wildcard, we can set the value of wildcards for \ (0 \) , then deformed at \ (\ sum \ limits_ {i = 0} ^ {n-1} a_i * b_i * (a_i-b_i) ^ 2 = 0 \)

Exhibition开得Itaru \ (\ sum \ limits_ {i = 0} ^ {n-1} a_i ^ 3 * b_i-2a_i ^ 2 * b_i ^ 2 + a_i * b_i ^ 3 \)

We can consider these three separate

For one \ (\ sum \ limits_ {i = 0} ^ {n-1} a_i ^ 3 * b_i \)

Set \ (a ^ { '} \ ) of \ (A \) inverted, \ (J = Ni-. 1 \) , the answer is \ (\ sum \ limits_ {i = 0} ^ {n-1} a_j ^ { '3} * b_i \)

Is then rolled up, the volume is determined after completion \ (i = (m-1 \ sim n-1) \) which coefficients are zero, the \ (i-m + 2 \ ) was added answers

#include<bits/stdc++.h>
using namespace std;
namespace red{
#define int long long
    inline int read()
    {
        int x=0;char ch,f=1;
        for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
        if(ch=='-') f=0,ch=getchar();
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return f?x:-x;
    }
    const int N=3e5+10,p=998244353,g=3,gi=332748118;
    int n,m,limit,len;
    char a[N],b[N];
    int pos[N<<2];
    int ret[N],num;
    int a1[N<<2],b1[N<<2],c[N<<2];
    inline int fast(int x,int k)
    {
        int ret=1;
        while(k)
        {
            if(k&1) ret=ret*x%p;
            x=x*x%p;
            k>>=1;
        }
        return ret;
    }
    inline void ntt(int *a,int inv)
    {
        for(int i=0;i<limit;++i)
            if(i<pos[i]) swap(a[i],a[pos[i]]);
        for(int mid=1;mid<limit;mid<<=1)
        {
            int Wn=fast(inv?g:gi,(p-1)/(mid<<1));
            for(int r=mid<<1,j=0;j<limit;j+=r)
            {
                int w=1;
                for(int k=0;k<mid;++k,w=w*Wn%p)
                {
                    int x=a[j+k],y=w*a[j+k+mid]%p;
                    a[j+k]=(x+y)%p;
                    a[j+k+mid]=(x-y)%p;
                    if(a[j+k+mid]<0) a[j+k+mid]+=p;
                }
            }
        }
        if(inv) return;
        inv=fast(limit,p-2);
        for(int i=0;i<limit;++i) a[i]=a[i]*inv%p;
    }
    inline void work(int *a,int *b,int opt)
    {
        ntt(a,1);ntt(b,1);
        for(int i=0;i<limit;++i) c[i]=c[i]+a[i]*b[i]*opt;
    }
    inline void main()
    {
        m=read(),n=read();
        scanf("%s%s",a,b);
        for(int i=0;i<m;++i)
        {
            if(a[i]=='*') a[i]=0;
            else a[i]=a[i]-'a'+1;
        }
        for(int i=0;i<n;++i)
        {
            if(b[i]=='*') b[i]=0;
            else b[i]=b[i]-'a'+1;
        }
        reverse(a,a+m);
        for(limit=1;limit<=n+m;limit<<=1) ++len;
        for(int i=0;i<limit;++i) pos[i]=(pos[i>>1]>>1)|((i&1)<<(len-1));
        for(int i=0;i<m;++i) a1[i]=a[i]*a[i]*a[i];
        for(int i=0;i<n;++i) b1[i]=b[i];
        work(a1,b1,1);
        for(int i=0;i<limit;++i) a1[i]=b1[i]=0;
        for(int i=0;i<m;++i) a1[i]=a[i]*a[i];
        for(int i=0;i<n;++i) b1[i]=b[i]*b[i];
        work(a1,b1,-2);
        for(int i=0;i<limit;++i) a1[i]=b1[i]=0;
        for(int i=0;i<m;++i) a1[i]=a[i];
        for(int i=0;i<n;++i) b1[i]=b[i]*b[i]*b[i];
        work(a1,b1,1);
        ntt(c,0);
        for(int i=m-1;i<n;++i)
        {
            if(!c[i]) ret[++num]=i-m+2;
        }
        printf("%lld\n",num);
        for(int i=1;i<=num;++i) printf("%lld ",ret[i]);
    }
}
signed main()
{
    red::main();
    return 0;
}

Guess you like

Origin www.cnblogs.com/knife-rose/p/12053200.html