結果

問題 No.2626 Similar But Different Name
ユーザー KKT89KKT89
提出日時 2024-02-09 22:46:27
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 198 ms / 3,000 ms
コード長 5,339 bytes
コンパイル時間 3,523 ms
コンパイル使用メモリ 230,792 KB
実行使用メモリ 105,932 KB
最終ジャッジ日時 2024-09-28 15:56:09
合計ジャッジ時間 7,482 ms
ジャッジサーバーID
(参考情報)
judge2 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
6,820 KB
testcase_01 AC 2 ms
6,816 KB
testcase_02 AC 2 ms
6,820 KB
testcase_03 AC 2 ms
6,820 KB
testcase_04 AC 2 ms
6,816 KB
testcase_05 AC 1 ms
6,816 KB
testcase_06 AC 2 ms
6,816 KB
testcase_07 AC 3 ms
6,820 KB
testcase_08 AC 2 ms
6,816 KB
testcase_09 AC 2 ms
6,816 KB
testcase_10 AC 3 ms
6,816 KB
testcase_11 AC 3 ms
6,816 KB
testcase_12 AC 2 ms
6,820 KB
testcase_13 AC 3 ms
6,816 KB
testcase_14 AC 3 ms
6,820 KB
testcase_15 AC 3 ms
6,820 KB
testcase_16 AC 3 ms
6,816 KB
testcase_17 AC 3 ms
6,816 KB
testcase_18 AC 182 ms
105,932 KB
testcase_19 AC 88 ms
54,676 KB
testcase_20 AC 88 ms
54,644 KB
testcase_21 AC 83 ms
54,652 KB
testcase_22 AC 191 ms
101,896 KB
testcase_23 AC 195 ms
101,796 KB
testcase_24 AC 188 ms
100,744 KB
testcase_25 AC 189 ms
101,156 KB
testcase_26 AC 192 ms
101,784 KB
testcase_27 AC 191 ms
101,932 KB
testcase_28 AC 182 ms
101,408 KB
testcase_29 AC 194 ms
100,588 KB
testcase_30 AC 198 ms
101,064 KB
testcase_31 AC 189 ms
101,572 KB
testcase_32 AC 186 ms
102,032 KB
testcase_33 AC 194 ms
101,952 KB
testcase_34 AC 191 ms
100,676 KB
testcase_35 AC 195 ms
101,808 KB
testcase_36 AC 197 ms
100,688 KB
testcase_37 AC 198 ms
105,924 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline double time() {
    return static_cast<long double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

// https://github.com/kth-competitive-programming/kactl/blob/main/content/numerical/FastFourierTransform.h
// https://github.com/kth-competitive-programming/kactl/blob/main/content/numerical/FastFourierTransformMod.h
#include<complex>
struct FFT{
    using cpx = complex<double>;

    void fft(vector<cpx>& a){
        int n = a.size(), L = 0;
        while(n > 1){
            n >>= 1;
            L++;
        }
        n = a.size();
        static vector<complex<long double>> R(2, 1);
        static vector<cpx> rt(2, 1);  // (^ 10% faster if double)
        for(static int k = 2; k < n; k *= 2) {
            R.resize(n);
            rt.resize(n);
            auto x = polar(1.0L, acos(-1.0L) / k);
            for(int i = k; i < 2 * k; ++i) {
                rt[i] = R[i] = i & 1 ? R[i / 2] * x : R[i / 2];
            }
        }
        vector<int> rev(n);
        for(int i = 0; i < n; ++i) {
            rev[i] = (rev[i / 2] | (i & 1) << L) / 2;
        }
        for(int i = 0; i < n; ++i) {
            if(i < rev[i]) swap(a[i], a[rev[i]]);
        }
        for(int k = 1; k < n; k *= 2){
            for(int i = 0; i < n; i += 2 * k) {
                for(int j = 0; j < k; ++j) {
                    cpx z = rt[j + k] * a[i + j + k];
                    a[i + j + k] = a[i + j] - z;
                    a[i + j] += z;
                }
            }
        }
    }

    vector<ll> conv(const vector<ll>& a, const vector<ll>& b){
        if(a.empty() or b.empty()) return {};
        vector<ll> res(a.size() + b.size() - 1);
        int L = 0, n = 1;
        while(n <= res.size()) {
            n <<= 1;
            L++;
        }

        vector<cpx> in(n), out(n);
        copy(a.begin(), a.end(), begin(in));
        for(int i = 0; i < b.size(); ++i) {
            in[i].imag(b[i]);
        }
        fft(in);
        for(cpx& x : in) x *= x;
        for(int i = 0; i < n; ++i) {
            out[i] = in[-i & (n - 1)] - conj(in[i]);
        }
        fft(out);
        for(int i = 0; i < res.size(); ++i) {
            res[i] = llround(imag(out[i]) / (4 * n));
        }
        return res;
    }

    vector<ll> convmod(const vector<ll>& a, const vector<ll>& b, int mod){
        if(a.empty() or b.empty()) return {};
        vector<ll> res(a.size() + b.size() - 1);
        int B = 0, n = 1, cut = (int)sqrt(mod);
        while(n <= res.size()) {
            n <<= 1;
            B++;
        }
        vector<cpx> L(n), R(n), outs(n), outl(n);
        for(int i = 0; i < a.size(); ++i) {
            L[i] = cpx((int)a[i] / cut, (int)a[i] % cut);
        }
        for(int i = 0; i < b.size(); ++i) {
            R[i] = cpx((int)b[i] / cut, (int)b[i] % cut);
        }
        fft(L);
        fft(R);
        for(int i = 0; i < n; ++i) {
            int j = -i & (n - 1);
            outl[j] = (L[i] + conj(L[j])) * R[i] / (2.0 * n);
            outs[j] = (L[i] - conj(L[j])) * R[i] / (2.0 * n) / 1i;
        }
        fft(outl);
        fft(outs);
        for(int i = 0; i < res.size(); ++i) {
            ll av = ll(real(outl[i]) + .5), cv = ll(imag(outs[i]) + .5);
            ll bv = ll(imag(outl[i]) + .5) + ll(real(outs[i]) + .5);
            res[i] = ((av % mod * cut + bv) % mod * cut + cv) % mod;
        }
        return res;
    }
};

vector<int> Zalgo(string s){
    int n=s.size();
    vector<int> a(n,0);
    int from=-1,last=-1;
    for(int i=1;i<n;i++){
        int &same=a[i];
        if(from!=-1){
            same=min(a[i-from],last-i);
            same=max(0,same);
        }
        while(i+same<n&&s[same]==s[i+same]){
            same++;
        }
        if(last<i+same){
            last=i+same;
            from=i;
        }
    }
    a[0]=n;
    return a;
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n,m,k; cin >> n >> m >> k;
    string s,t; cin >> s >> t;

    vector<bool> ok(n);
    {
        string S = s, T = t;
        for (int i = 0; i < n; ++i) {
            if (s[i] >= 'a') {
                S[i] -= 'a';
                S[i] += 'A';
            }
        }
        for (int i = 0; i < m; ++i) {
            if (t[i] >= 'a') {
                T[i] -= 'a';
                T[i] += 'A';
            }
        }
        T = T + "$" + S;
        auto Z = Zalgo(T);
        for (int i = 0; i < n; ++i) {
            if (Z[m+1+i] >= m) {
                ok[i] = true;
            }
        }
    }
    vector<ll> sb(n), tb(m);
    for (int i = 0; i < n; ++i) {
        if (s[i] >= 'a') sb[i] = 1;
        else sb[i] = -1;
    }
    for (int i = 0; i < m; ++i) {
        if (t[i] >= 'a') tb[m-1-i] = 1;
        else tb[m-1-i] = -1;
    }
    FFT fft;
    auto conv = fft.conv(sb, tb);
    int res = 0;
    for (int i = 0; i < n; ++i) {
        if (ok[i]) {
            int idx = i+m-1;
            if (m-k-k <= conv[idx] and conv[idx] < m) {
                res += 1;
            }
        }
    }
    cout << res << endl;
}
0