• bzoj4259


    fft

    搞一个生成函数

    对于每位A(j)=Σi=1->m (a[i]-b[i+j])^2*a[i]*b[i+j]

    如果A(j)=0说明这位匹配

    如果这位是*那么a[i]=0否则等于字母-'a'+1,b也是这样构造

    然后我们翻转a串就可以加速了

    #include<bits/stdc++.h>
    using namespace std;
    #define pi acos(-1)
    const int N = (1 << 20) + 5;
    int n = 1, n1, n2, k;
    char s1[N], s2[N];
    int t[N], ans[N];
    struct data {
        double a, b;
        data() { a = 0; b = 0; }
        data(double _, double __) : a(_), b(__) {}
        data friend operator + (const data &a, const data &b) { return data(a.a + b.a, a.b + b.b); }
        data friend operator - (const data &a, const data &b) { return data(a.a - b.a, a.b - b.b); }
        data friend operator * (const data &a, const data &b) { return data(a.a * b.a - a.b * b.b, a.a * b.b + a.b * b.a); }
    } a0[N], b0[N], a1[N], b1[N], a2[N], b2[N];
    void fft(data *a, int f)
    {
        for(int i = 0; i < n; ++i) 
        {
            int t = 0;
            for(int j = 0; j < k; ++j) if(i >> j & 1) t |= 1 << (k - j - 1);
            if(i < t) swap(a[i], a[t]); 
        }
        for(int l = 2; l <= n; l <<= 1) 
        {
            int m = l >> 1;
            data w = data(cos(pi / m), f * sin(pi / m));
            for(int i = 0; i < n; i += l) 
            {
                data t = data(1, 0);
                for(int k = 0; k < m; ++k, t = t * w)
                {
                    data x = a[i + k], y = t * a[i + k + m];
                    a[i + k] = x + y;
                    a[i + k + m] = x - y;
                }
            }
        }
    }
    int main()
    {
        scanf("%d%d%s%s", &n1, &n2, s1, s2);
        reverse(s1, s1 + n1);
        --n1;
        --n2;
        for(int i = 0; i <= n1; ++i) if(s1[i] != '*') 
        {
            double x = s1[i] - 'a' + 1;
            a0[i] = data(x, 0);
            a1[i] = data(x * x, 0);
            a2[i] = data(x * x * x, 0);
        }    
        for(int i = 0; i <= n2; ++i) if(s2[i] != '*') 
        {
            double x = s2[i] - 'a' + 1;
            b0[i] = data(x, 0);
            b1[i] = data(-2 * x * x, 0); 
            b2[i] = data(x * x * x, 0);
        }    
        while(n <= n1 + n2) n <<= 1, ++k; 
        fft(a0, 1);
        fft(a1, 1);
        fft(a2, 1);
        fft(b0, 1);
        fft(b1, 1);
        fft(b2, 1);
        for(int i = 0; i < n; ++i) a2[i] = a2[i] * b0[i], a1[i] = a1[i] * b1[i], a0[i] = a0[i] * b2[i], a2[i] = a2[i] + a1[i] + a0[i];
        fft(a2, -1);
        for(int i = 0; i < n; ++i) t[i] = (int)(a2[i].a / n + 0.1);
        for(int i = 0; i <= n2 - n1; ++i) if(t[i + n1] == 0) ans[++ans[0]] = i + 1;
        printf("%d
    ", ans[0]);
        for(int i = 1; i < ans[0]; ++i) printf("%d ", ans[i]);
        printf("%d
    ", ans[ans[0]]);
        return 0;
    }
    View Code
  • 相关阅读:
    PAT甲题题解-1106. Lowest Price in Supply Chain (25)-(dfs计算树的最小层数)
    PAT甲题题解-1105. Spiral Matrix (25)-(模拟顺时针矩阵)
    PAT甲题题解-1102. Invert a Binary Tree (25)-(建树,水题)
    PAT甲题题解-1101. Quick Sort (25)-大水题
    PAT甲级题解-1100. Mars Numbers (20)-字符串处理
    XJOI网上同步训练DAY1 T2
    XJOI网上同步训练DAY1 T1
    BZOJ 1061 志愿者招募
    BZOJ 2432 兔农
    KMP算法总♂结
  • 原文地址:https://www.cnblogs.com/19992147orz/p/8043407.html
Copyright © 2020-2023  润新知