QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#417925#7187. Hardcore String CountingpandapythonerAC ✓4332ms47560kbC++1410.0kb2024-05-23 02:24:052024-05-23 02:24:06

Judging History

This is the latest submission verdict.

  • [2024-05-23 02:24:06]
  • Judged
  • Verdict: AC
  • Time: 4332ms
  • Memory: 47560kb
  • [2024-05-23 02:24:05]
  • Submitted

answer

#include <bits/stdc++.h>

using namespace std;

#define int long long
#define ll long long
#define flt double
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()

const ll mod = 998244353;

ll bin_pow(ll x, ll n) {
    if (n == 0) {
        return 1;
    }
    ll a = bin_pow(x, n / 2);
    a = (a * a) % mod;
    if (n & 1) {
        a = (a * x) % mod;
    }
    return a;
}

ll rev(ll x) {
    return bin_pow(x, mod - 2);
}

namespace fft {
    ll w0 = 31;
    const ll mx_w0_pw = 23;
    ll mxn;
    ll mxnk;

    vector<ll> rv;
    vector<ll> wpws;

    void build(int nk) {
        mxnk = nk;
        mxn = (1 << mxnk);
        rv.resize(mxn);
        wpws.resize(mxn);
        rv[0] = 0;
        for (int i = 1; i < mxn; i += 1) {
            rv[i] = (rv[i >> 1] >> 1);
            if (i & 1) {
                rv[i] += (1 << (mxnk - 1));
            }
        }
    }

    void fft(vector<ll>& a, int nk) {
        int n = (1 << nk);
        for (int i = 0; i < n; i += 1) {
            int rvi = (rv[i] >> (mxnk - nk));
            if (rvi < i) {
                swap(a[i], a[rvi]);
            }
        }
        ll w = bin_pow(w0, 1 << (mx_w0_pw - nk));
        wpws[0] = 1;
        for (int i = 1; i < n; i += 1) {
            wpws[i] = (wpws[i - 1] * w) % mod;
        }
        for (ll len = 1; len < n; len *= 2) {
            ll len2 = len + len;
            for (int i = 0; i < n; i += len2) {
                for (int j = 0; j < len; j += 1) {
                    ll mw = wpws[j * (n / len2)];
                    ll t = (a[i + j + len] * mw) % mod;
                    a[i + j + len] = a[i + j] - t;
                    if (a[i + j + len] < mod) {
                        a[i + j + len] += mod;
                    }
                    a[i + j] = a[i + j] + t;
                    if (a[i + j] >= mod) {
                        a[i + j] -= mod;
                    }
                }
            }
        }
    }

    void rev_fft(vector<ll>& a, int nk) {
        int n = (1 << nk);
        fft(a, nk);
        ll rvn = rev(n);
        reverse(a.begin() + 1, a.end());
        for (int i = 0; i < n; i += 1) {
            a[i] = (a[i] * rvn) % mod;
        }
    }

    vector<ll> mul_plnms(const vector<ll>& a, const vector<ll>& b) {
        int nk = 0;
        while ((1 << nk) < a.size() + b.size() - 1) {
            nk += 1;
        }
        int n = (1 << nk);
        vector<ll> ma(n), mb(n);
        for (int i = 0; i < a.size(); i += 1) {
            ma[i] = a[i];
        }
        for (int i = 0; i < b.size(); i += 1) {
            mb[i] = b[i];
        }
        fft(ma, nk);
        fft(mb, nk);
        for (int i = 0; i < n; i += 1) {
            ma[i] = (ma[i] * mb[i]) % mod;
        }
        rev_fft(ma, nk);
        while (ma.size() > 1 && ma.back() == 0) {
            ma.pop_back();
        }
        return ma;
    }

    vector<ll> rev_plnm(const vector<ll>& a, int n) {
        static map<pair<int, vector<ll>>, vector<ll>> cash;
        auto pr = make_pair(n, a);
        if (cash.find(pr) != cash.end()) {
            return cash[pr];
        }
        int m = 1;
        int mk = 0;
        vector<ll> b = { rev(a[0]) };
        while (m < n) {
            int t = m * 4;
            vector<ll> na(t, 0), nb(t, 0);
            for (int i = 0; i < m; i += 1) {
                nb[i] = b[i];
            }
            for (int i = 0; i < min((int)(a.size()), m + m); i += 1) {
                na[i] = a[i];
            }
            fft(nb, mk + 2);
            fft(na, mk + 2);
            for (int i = 0; i < t; i += 1) {
                nb[i] = (2 * nb[i] + mod - ((na[i] * nb[i]) % mod * nb[i]) % mod) % mod;
            }
            rev_fft(nb, mk + 2);
            b.swap(nb);
            m = m + m;
            mk += 1;
            b.resize(m);
        }
        b.resize(n, 0);
        cash[pr] = b;
        return b;
    }

    vector<ll> mul_plnms(vector<vector<ll>>& a, int l, int r) {
        if (l > r) {
            return { 1 };
        }
        if (l == r) {
            return a[l];
        }
        int m = (l + r) / 2;
        return mul_plnms(mul_plnms(a, l, m), mul_plnms(a, m + 1, r));
    }

    vector<ll> mul_plnms(vector<vector<ll>>& a) {
        return mul_plnms(a, 0, (int)(a.size()) - 1);
    }

    vector<ll> div_plnms(vector<ll> a, vector<ll> b) {
        while (!b.empty() && b.back() == 0) {
            b.pop_back();
        }
        if (b.empty()) {
            assert(0);
        }
        if (a.size() < b.size()) {
            return { 0 };
        }
        int n = (int)a.size() - 1;
        int m = (int)b.size() - 1;
        reverse(all(a));
        reverse(all(b));
        vector<ll> rvb = rev_plnm(b, n - m + 1);
        vector<ll> t = mul_plnms(rvb, a);
        t.resize(n - m + 1);
        reverse(all(t));
        return t;
    }

    vector<ll> remainder(vector<ll>& a, vector<ll> b) {
        while (!b.empty() && b.back() == 0) {
            b.pop_back();
        }
        if (b.empty()) {
            assert(0);
        }
        if (a.size() < b.size()) {
            return a;
        }
        auto t = div_plnms(a, b);
        auto r = mul_plnms(b, t);
        r.resize((int)b.size() - 1);
        for (int i = 0; i < (int)b.size() - 1; i += 1) {
            r[i] = (a[i] - r[i]);
            if (r[i] < 0) {
                r[i] += mod;
            }
        }
        return r;
    }

    void evaluate_dfs_1(int v, int tl, int tr, vector<ll>& p, vector<vector<ll>>& mltpls) {
        if (tl == tr) {
            mltpls[v] = { (mod - p[tl]) % mod, 1 };
            return;
        }
        int tm = (tl + tr) / 2;
        evaluate_dfs_1(v + v, tl, tm, p, mltpls);
        evaluate_dfs_1(v + v + 1, tm + 1, tr, p, mltpls);
        mltpls[v] = mul_plnms(mltpls[v + v], mltpls[v + v + 1]);
    }

    void evaluate_dfs_2(int v, int tl, int tr, vector<vector<ll>>& mltpls, vector<ll>& rs, vector<ll> a) {
        a = remainder(a, mltpls[v]);
        if (tl == tr) {
            if (a.empty()) {
                rs[tl] = 0;
            } else {
                rs[tl] = a[0];
            }
            return;
        }
        int tm = (tl + tr) / 2;
        evaluate_dfs_2(v + v, tl, tm, mltpls, rs, a);
        evaluate_dfs_2(v + v + 1, tm + 1, tr, mltpls, rs, a);
    }

    vector<ll> evaluate(const vector<ll>& a, vector<ll>& p) {
        if (p.size() == 0) {
            return {};
        }
        int n = p.size();
        vector<vector<ll>> mltpls(n * 4);
        vector<ll> rs(n);
        evaluate_dfs_1(1, 0, n - 1, p, mltpls);
        evaluate_dfs_2(1, 0, n - 1, mltpls, rs, a);
        return rs;
    }

    vector<ll> exp_x(int n) {
        vector<ll> rs(n);
        rs[0] = 1;
        for (int i = 1; i < n; i += 1) {
            rs[i] = (rs[i - 1] * rev(i)) % mod;
        }
        return rs;
    }

    vector<ll> exp_mns_x(int n) {
        vector<ll> rs(n);
        rs[0] = 1;
        for (int i = 1; i < n; i += 1) {
            rs[i] = (rs[i - 1] * rev(mod - i)) % mod;
        }
        return rs;
    }


    ll get_kth_of_quotient(vector<ll> p, vector<ll> q, ll k) {
        vector<ll> qinv = rev_plnm(q, k + 1);
        auto quotient = mul_plnms(p, qinv);
        return quotient[k];
    }
};  // namespace fft

int n;
ll m;
string s;
vector<int> p;


void count_p() {
    p.resize(n);
    p[0] = 0;
    for (int i = 1; i < n; i += 1) {
        int j = p[i - 1];
        while (j > 0 and s[j] != s[i]) {
            j = p[j - 1];
        }
        if (s[j] == s[i]) {
            j += 1;
        }
        p[i] = j;
    }
}


ll solve() {
    if (n == m) {
        return 1;
    }
    const ll alpha = 26;
    vector<ll> d(n);
    count_p();
    int j = p[n - 1];
    while (j > 0) {
        d[n - j] = 1;
        j = p[j - 1];
    }
    vector<ll> dp(n + 1);
    ll rvalpha = rev(alpha);
    ll rv_pw = bin_pow(rvalpha, n);
    dp[n] = rv_pw;
    vector<ll> pws(n);
    for (int i = 0; i < n; i += 1) {
        pws[i] = bin_pow(rvalpha, i);
    }
    vector<ll> a(n + 1);
    a[n] = 1;
    a[n - 1] = (a[n - 1] + mod - 1) % mod;
    a[0] = (a[0] + rv_pw) % mod;
    for (int j = 0; j < n; j += 1) {
        if (d[j]) {
            a[n - j] = (a[n - j] + pws[j]) % mod;
            a[n - j - 1] = (a[n - j - 1] + mod - pws[j]) % mod;
        }
    }
    vector<ll> b(n + 2);
    for (int i = 0; i <= n; i += 1) {
        b[i] = (b[i] + mod - a[i]) % mod;
        b[i + 1] = (b[i + 1] + a[i]) % mod;
    }
    /*
    for (int i = n + 1; i <= m; i += 1) {
        dp[i] = 0;
        for (int j = 0; j <= n; j += 1) {
            dp[i] = ((dp[i] - b[j] * dp[i - n - 1 + j]) % mod + mod) % mod;
        }
    }
    */
    function<vector<ll>(ll)> super_pow;
    super_pow = [&](ll k) {
        if (k == 0) {
            vector<ll> f(n + 1);
            f[0] = 1;
            return f;
        }
        auto f = super_pow(k / 2);
        f = fft::mul_plnms(f, f);
        f = fft::remainder(f, b);
        f.resize(n + 1);
        if (k & 1) {
            f.insert(f.begin(), 0);
            for (int i = 0; i <= n; i += 1) {
                f[i] = ((f[i] - b[i] * f[n + 1]) % mod + mod) % mod;
            }
            f.resize(n + 1);
        }
        return f;
        };
    auto aboba = super_pow(m - 1);
    ll first = 0;
    for (int i = 0; i <= n; i += 1) {
        first = (first + dp[i] * aboba[i]) % mod;
    }
    aboba.insert(aboba.begin(), 0);
    aboba = fft::remainder(aboba, b);
    ll second = 0;
    for (int i = 0; i <= n; i += 1) {
        second = (second + dp[i] * aboba[i]) % mod;
    }
    ll rs = (second - first + mod) % mod;
    rs = (rs * bin_pow(alpha, m)) % mod;
    return rs;
}


int32_t main() {
    fft::build(20);
    if (1) {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
    }
    cin >> n >> m;
    cin >> s;
    ll rs = solve();
    cout << solve() << "\n";
    return 0;
}

这程序好像有点Bug,我给组数据试试?

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 6ms
memory: 19384kb

input:

6 7
aaaaaa

output:

25

result:

ok answer is '25'

Test #2:

score: 0
Accepted
time: 0ms
memory: 19552kb

input:

3 5
aba

output:

675

result:

ok answer is '675'

Test #3:

score: 0
Accepted
time: 0ms
memory: 19564kb

input:

1 1
a

output:

1

result:

ok answer is '1'

Test #4:

score: 0
Accepted
time: 0ms
memory: 19396kb

input:

5 7
ababa

output:

675

result:

ok answer is '675'

Test #5:

score: 0
Accepted
time: 0ms
memory: 19496kb

input:

1 3
a

output:

625

result:

ok answer is '625'

Test #6:

score: 0
Accepted
time: 0ms
memory: 19548kb

input:

10 536870912
njjnttnjjn

output:

826157401

result:

ok answer is '826157401'

Test #7:

score: 0
Accepted
time: 1728ms
memory: 33100kb

input:

65535 536870912
aaaoaaaoaaaoaaayaaaoaaaoaaaoaaayaaaoaaaoaaaoaaayaaaoaaaoaaaoaaaeaaaoaaaoaaaoaaayaaaoaaaoaaaoaaayaaaoaaaoaaaoaaayaaaoaaaoaaaoaaaeaaaoaaaoaaaoaaayaaaoaaaoaaaoaaayaaaoaaaoaaaoaaayaaaoaaaoaaaoaaaeaaaoaaaoaaaoaaayaaaoaaaoaaaoaaayaaaoaaaoaaaoaaayaaaoaaaoaaaoaaaraaaoaaaoaaaoaaayaaaoaaaoaaao...

output:

996824286

result:

ok answer is '996824286'

Test #8:

score: 0
Accepted
time: 3980ms
memory: 47552kb

input:

99892 536870912
wwwwbwwwwbwwwwqwwwwbwwwwbwwwwqwwwwbwwwwbwwwweewwwwbwwwwbwwwwqwwwwbwwwwbwwwwqwwwwbwwwwbwwwweewwwwbwwwwbwwwwqwwwwbwwwwbwwwwqwwwwbwwwwbwwwwawwwwbwwwwbwwwwqwwwwbwwwwbwwwwqwwwwbwwwwbwwwweewwwwbwwwwbwwwwqwwwwbwwwwbwwwwqwwwwbwwwwbwwwweewwwwbwwwwbwwwwqwwwwbwwwwbwwwwqwwwwbwwwwbwwwwawwwwbwwwwb...

output:

718505966

result:

ok answer is '718505966'

Test #9:

score: 0
Accepted
time: 4037ms
memory: 47556kb

input:

100000 536870912
rrmrrqrrmrrcrrmrrqrrmrrbrrmrrqrrmrrcrrmrrqrrmrrnnrrmrrqrrmrrcrrmrrqrrmrrbrrmrrqrrmrrcrrmrrqrrmrrttrrmrrqrrmrrcrrmrrqrrmrrbrrmrrqrrmrrcrrmrrqrrmrrnnrrmrrqrrmrrcrrmrrqrrmrrbrrmrrqrrmrrcrrmrrqrrmrrarrmrrqrrmrrcrrmrrqrrmrrbrrmrrqrrmrrcrrmrrqrrmrrnnrrmrrqrrmrrcrrmrrqrrmrrbrrmrrqrrmrrcrrm...

output:

824845147

result:

ok answer is '824845147'

Test #10:

score: 0
Accepted
time: 4205ms
memory: 47452kb

input:

99892 1000000000
ggggjggggjggggxggggjggggjggggxggggjggggjggggeeggggjggggjggggxggggjggggjggggxggggjggggjggggeeggggjggggjggggxggggjggggjggggxggggjggggjggggbggggjggggjggggxggggjggggjggggxggggjggggjggggeeggggjggggjggggxggggjggggjggggxggggjggggjggggeeggggjggggjggggxggggjggggjggggxggggjggggjggggbggggjgggg...

output:

971128221

result:

ok answer is '971128221'

Test #11:

score: 0
Accepted
time: 4105ms
memory: 47348kb

input:

100000 625346716
kwfuguxrbiwlvyqsbujelgcafpsnxsgefwxqoeeiwoolreyxvaahagoibdrznebsgelthdzqwxcdglvbpawhdgaxpiyjglzhiamhtptsyyzyyhzjvnqfyqhnrtbwgeyotmltodidutmyvzfqfctnqugmrdtuyiyttgcsjeupuuygwqrzfibxhaefmbtzfhvopmtwwycopheuacgwibxlsjpupdmchvzneodwuzzteqlzlfizpleildqqpcuiechcwearxlvplatyrzxfochdfjqcmzt...

output:

0

result:

ok answer is '0'

Test #12:

score: 0
Accepted
time: 2377ms
memory: 36148kb

input:

65536 35420792
pkmyknsqmhwuevibxjgrftrinkulizarxbkmgorddvuvtrhdadnlxfrxsyqhueuefdkanysaixmhbdqyskjdrzntlaqtwoscxldmyzahzwximvjgsjuddejbsbwtxgkbzfzdusucccohjwjuaasnkindxjjtxdbxmitcixrcmawdezafgnigghdtoyzazyfedzsuwsrlkdtarcmzqnszgnyiqvzamjtamvfrhzucdsfscyzdbvbxutwraktnmfrdfbejcbhjcgczgwiucklwydmuuozlu...

output:

0

result:

ok answer is '0'

Test #13:

score: 0
Accepted
time: 4332ms
memory: 47472kb

input:

100000 1000000000
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn...

output:

545362217

result:

ok answer is '545362217'

Test #14:

score: 0
Accepted
time: 3996ms
memory: 47560kb

input:

100000 536870911
ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg...

output:

332737929

result:

ok answer is '332737929'

Test #15:

score: 0
Accepted
time: 3976ms
memory: 47548kb

input:

100000 536870911
qodtwstdnykduvzvvvzmpawqaajvcdatuzzjisoezaqtvqhghmixvlfyhznvrlhdslyyhxoqchflfdjiefikpfrykekhjqywxpwmihiojcfzcmqelrkddbpkcnqcaopdyhldawyrvkqfbqpybewrtusifbfdtxiflxtkzdjqbocozdpupunehraytkhqnobhzeohkvbjyrdfebstqfjlvrcabimlybsnuaqgfcldvklwnyuywvfpdqwmortctexzaufmazyatybltglyonllufofiyr...

output:

592710827

result:

ok answer is '592710827'

Test #16:

score: 0
Accepted
time: 0ms
memory: 19840kb

input:

100000 100000
ciawhxojdqnivfonswbklnoocigwmkbjtkzahqgysihfdeqhialusobeeazqaqzryakqycapfswxpithldpuiflxzpgsysjwnpinfubqlyadphswzvzbrxcdbbhavtzkvwrcqecfnzawisgkvsopjnfzfnlecuesnffqzcknunwsxlrbvdzqbduypfrwgqqnrjstxgjaeuqxxajfbmidkwhrgkpjduftivfwnuugxomyznpbtbcstdkdaitvpdtuvyzipygztosvjwwdascbqthqdgkbit...

output:

1

result:

ok answer is '1'

Test #17:

score: 0
Accepted
time: 4202ms
memory: 47464kb

input:

100000 1000000000
zujpixywgppdzqtwikoyhvlwqvxrfdylopuqgprrqpgqmgfkmhbucwkgdljyfzzbtaxxnltmbptwhknjjqlbeuiowdblqppqeeuunexkghdxjtbidlacmycgwvulgaeazyiwzedaxhtskacflodouylwxfjydzfbthotdwrfcpwrkcgnxpjsmkafaaojlctmqckabidgalvptziemzphncrgtqxlvllgwwgkoqxwhziuxvkadgaohdlceuggwwzmpywsgoecwwhhbotaleesjexdxg...

output:

879141501

result:

ok answer is '879141501'

Extra Test:

score: 0
Extra Test Passed