QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#348485#8340. 3 Sumucup-team1191#RE 103ms13312kbC++2019.3kb2024-03-09 18:53:502024-10-13 18:48:22

Judging History

你现在查看的是最新测评结果

  • [2024-10-13 18:48:22]
  • 管理员手动重测本题所有得分≥97分的提交记录
  • 测评结果:RE
  • 用时:103ms
  • 内存:13312kb
  • [2024-09-20 10:20:30]
  • hack成功,自动添加数据
  • (/hack/848)
  • [2024-03-18 21:48:05]
  • hack成功,自动添加数据
  • (/hack/579)
  • [2024-03-18 21:45:33]
  • hack成功,自动添加数据
  • (/hack/578)
  • [2024-03-09 18:53:51]
  • 评测
  • 测评结果:100
  • 用时:93ms
  • 内存:13392kb
  • [2024-03-09 18:53:50]
  • 提交

answer

/*
    author:  Maksim1744
    created: 09.03.2024 12:03:07
*/

#include "bits/stdc++.h"

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;

using ll = long long;
using ld = long double;

#define mp   make_pair
#define pb   push_back
#define eb   emplace_back

#define sum(a)     ( accumulate ((a).begin(), (a).end(), 0ll))
#define mine(a)    (*min_element((a).begin(), (a).end()))
#define maxe(a)    (*max_element((a).begin(), (a).end()))
#define mini(a)    ( min_element((a).begin(), (a).end()) - (a).begin())
#define maxi(a)    ( max_element((a).begin(), (a).end()) - (a).begin())
#define lowb(a, x) ( lower_bound((a).begin(), (a).end(), (x)) - (a).begin())
#define uppb(a, x) ( upper_bound((a).begin(), (a).end(), (x)) - (a).begin())

template<typename T>             vector<T>& operator--            (vector<T> &v){for (auto& i : v) --i;            return  v;}
template<typename T>             vector<T>& operator++            (vector<T> &v){for (auto& i : v) ++i;            return  v;}
template<typename T>             istream& operator>>(istream& is,  vector<T> &v){for (auto& i : v) is >> i;        return is;}
template<typename T>             ostream& operator<<(ostream& os,  vector<T>  v){for (auto& i : v) os << i << ' '; return os;}
template<typename T, typename U> pair<T,U>& operator--           (pair<T, U> &p){--p.first; --p.second;            return  p;}
template<typename T, typename U> pair<T,U>& operator++           (pair<T, U> &p){++p.first; ++p.second;            return  p;}
template<typename T, typename U> istream& operator>>(istream& is, pair<T, U> &p){is >> p.first >> p.second;        return is;}
template<typename T, typename U> ostream& operator<<(ostream& os, pair<T, U>  p){os << p.first << ' ' << p.second; return os;}
template<typename T, typename U> pair<T,U> operator-(pair<T,U> a, pair<T,U> b){return mp(a.first-b.first, a.second-b.second);}
template<typename T, typename U> pair<T,U> operator+(pair<T,U> a, pair<T,U> b){return mp(a.first+b.first, a.second+b.second);}
template<typename T, typename U> void umin(T& a, U b){if (a > b) a = b;}
template<typename T, typename U> void umax(T& a, U b){if (a < b) a = b;}

#ifdef HOME
#define SHOW_COLORS
#include "/mnt/c/Libs/tools/print.cpp"
#else
#define show(...) void(0)
#define debugf(fun)   fun
#define debugv(var)   var
#define mclock    void(0)
#define shows     void(0)
#define debug  if (false)
#define OSTREAM(...)    ;
#define OSTREAM0(...)   ;
#endif

const int basen = 18;
const ll base = 1e18;

// uncomment to multiply large numbers with fft
// basen should be even, at most 8
// with doubles in fft and basen = 8 works up to Big.v.size() = 1e6 (but fails for 1e6 + 5e4)
// #define BIGINT_USE_FFT

// division works in n^2 * log(base), where n = Big.v.size()

using T = ll;

array<ll, 19> pow10;

struct Big {
    vector<ll> v;
    bool minus = false;

    Big() {}
    Big(long long k) {
        if (k < 0) {
            minus = true;
            k = -k;
        }
        while (k) {
            v.push_back(k % base);
            k /= base;
        }
    }
    Big(string s) {
        if (s[0] == '-') {
            s.erase(s.begin());
            minus = true;
        }
        reverse(s.begin(), s.end());
        while (s.size() % basen != 0)
            s.push_back('0');
        reverse(s.begin(), s.end());
        for (int i = 0; i < s.size(); i += basen)
            v.push_back(stoll(s.substr(i, basen)));
        reverse(v.begin(), v.end());
        norm();
    }

    void modk(int k) {
        auto push_at = [&](int i) {
            while (i + 1 < v.size() && v[i] >= base) {
                while (v[i] >= base) {
                    v[i] -= base;
                    v[i + 1]++;
                }
                ++i;
            }
        };
        if (k <= basen) {
            while (v.size() > 1) {
                v.back() %= pow10[k] - 1;
                v[v.size() - 2] += v.back() * pow10[basen - k];
                v.back() = 0;
                push_at(v.size() - 2);
                if (v.back() == 0) v.pop_back();
            }
            norm();
            v[0] %= pow10[k] - 1;
            return;
        }
        while (v.size() > k / basen + 1) {
            ll x = v.back();
            v.back() -= x;
            int add_at = ((int)v.size() - 1) * basen % k;
            if (add_at % basen == 0) {
                v[add_at / basen] += x;
                push_at(add_at / basen);
            } else {
                v[add_at / basen] += pow10[add_at % basen] * (x % pow10[basen - add_at % basen]);
                v[add_at / basen + 1] += x / pow10[basen - add_at % basen];
                push_at(add_at / basen);
                push_at(add_at / basen + 1);
            }
            if (v.back() == 0) {
                v.pop_back();
            }
        }
        while (v.size() == k / basen + 1 && v.back() >= pow10[k - (v.size() - 1) * basen]) {
            ll x = v.back() / pow10[k - (v.size() - 1) * basen];
            v.back() %= pow10[k - (v.size() - 1) * basen];
            v[0] += x;
            push_at(0);
        }
        bool is0 = true;
        for (int i = 0; i + 1 < v.size(); ++i) {
            if (v[i] != pow10[basen] - 1) {
                is0 = false;
                break;
            }
        }
        if (v.back() != pow10[k - basen * (v.size() - 1)] - 1) {
            is0 = false;
        }
        if (is0) {
            v = {0};
        }
        norm();
    }

    void mulint(int x) {
        for (ll& u : v)
            u *= x;
        v.pb(0);
        for (int i = 0; i + 1 < v.size(); ++i) {
            v[i + 1] += v[i] / base;
            v[i] %= base;
        }
        norm();
    }

    int modint(int x) {
        ll basemod = base % x;
        ll ans = 0;
        ll pw = 1;
        for (ll u : v) {
            ans = (ans + u % x * pw) % x;
            pw = (pw * basemod) % x;
        }
        return ans;
    }

    Big &operator += (const Big &other) {
        if (minus == other.minus) {
            _add_(v, other.v);
        } else {
            if (_comp_(other.v, v)) {
                _sub_(v, other.v);
            } else {
                _sub2_(v, other.v);
                minus ^= 1;
            }
        }
        norm();
        return *this;
    }
    Big operator + (const Big &other) const {
        auto res = *this;
        return res += other;
    }

    Big operator - () const {
        Big res = *this;
        if (!v.empty()) res.minus ^= 1;
        return res;
    }
    Big &operator -= (const Big &other) {
        return *this += -other;
    }
    Big operator - (const Big &other) const {
        auto res = *this;
        return res -= other;
    }

    Big operator * (const Big &other) const {
        if (v.empty() || other.v.empty()) return 0;
        Big res;
        res.v = _mult_(v, other.v);
        res.minus = minus ^ other.minus;
        return res;
    }
    Big &operator *= (const Big &other) {
        return *this = *this * other;
    }

    Big operator / (const Big &other) const {
        Big res;
        res.v = _div_(v, other.v).first;
        res.minus = minus ^ other.minus;
        res.norm();
        return res;
    }
    Big &operator /= (const Big &other) {
        return *this = *this / other;
    }

    Big operator % (const Big &other) const {
        Big res;
        res.v = _div_(v, other.v).second;
        res.minus = minus ^ other.minus;
        res.norm();
        return res;
    }
    Big &operator %= (const Big &other) {
        return *this = *this % other;
    }

    int operator % (int m) const {
        long long p = 1;
        long long res = 0;
        for (int k : v) {
            res += k * p % m;
            p = p * base % m;
        }
        return res % m;
    }

    void norm() {
        while (!v.empty() && v.back() == 0)
            v.pop_back();
        if (v.empty()) {
            minus = false;
            v.pb(0);
        }
    }

    bool operator < (const Big &other) const {
        if (minus != other.minus) return minus;
        if (minus) return _comp_(other.v, v);
        else return _comp_(v, other.v);
    }
    bool operator > (const Big &other) const {
        return other < *this;
    }
    bool operator <= (const Big &other) const {
        return !(other < *this);
    }
    bool operator >= (const Big &other) const {
        return !(*this < other);
    }

    bool operator == (const Big &other) const {
        return minus == other.minus && v == other.v;
    }
    bool operator != (const Big &other) const {
        return !(*this == other);
    }

  private:
    static void _sub_(vector<T> &a, const vector<T> &b) {
        a.resize(max(a.size(), b.size()) + 1, 0);
        for (int i = 0; i < b.size(); ++i)
            a[i] -= b[i];
        for (int i = 0; i + 1 < b.size() || a[i] < 0; ++i) {
            if (a[i] < 0) {
                a[i] += base;
                --a[i + 1];
            }
        }
        assert(a.back() >= 0);
        while (!a.empty() && a.back() == 0)
            a.pop_back();
    }

    static void _sub2_(vector<T> &a, const vector<T> &b) {
        a.resize(max(a.size(), b.size()) + 1, 0);
        for (int i = 0; i < a.size(); ++i)
            a[i] = (i < b.size() ? b[i] : 0) - a[i];
        for (int i = 0; i + 1 < a.size(); ++i) {
            if (a[i] < 0) {
                a[i] += base;
                --a[i + 1];
            }
        }
        assert(a.back() >= 0);
        while (!a.empty() && a.back() == 0)
            a.pop_back();
    }

    static void _add_(vector<T> &a, const vector<T> &b) {
        a.resize(max(a.size(), b.size()) + 1, 0);
        for (int i = 0; i < b.size(); ++i)
            a[i] += b[i];
        for (int i = 0; i + 1 < b.size() || a[i] >= base; ++i) {
            if (a[i] >= base) {
                a[i] -= base;
                ++a[i + 1];
            }
        }
        while (!a.empty() && a.back() == 0)
            a.pop_back();
    }

    static bool _comp_(const vector<T> &a, const vector<T> &b) {
        if (a.size() != b.size())
            return a.size() < b.size();
        for (int i = (int)a.size() - 1; i >= 0; --i)
            if (a[i] != b[i])
                return a[i] < b[i];
        return false;
    }

    static vector<T> _mult_(const vector<T> &a, const vector<T> &b) {
        #ifdef BIGINT_USE_FFT
        // tested on a.v.size() = 1e6, b.v.size() = C, fft is better on C > ~500 : https://ideone.com/kSYLd8
        // if a.v.size() = b.v.size() = C, it's 380 : https://ideone.com/MJTo1Y
        if (min(a.size(), b.size()) > 380) {
            return _fft_mult_(a, b);
        }
        #endif

        return _slow_mult_(a, b);
    }

    static vector<T> _slow_mult_(const vector<T> &a, const vector<T> &b) {
        vector<long long> tmp(a.size() + b.size() + 1, 0);
        for (int i = 0; i < a.size(); ++i) {
            for (int j = 0; j < b.size(); ++j) {
                long long prod = 1ll * a[i] * b[j];
                long long div = prod / base;
                tmp[i + j] += prod - base * div;
                tmp[i + j + 1] += div;
            }
        }
        for (int i = 0; i + 1 < tmp.size(); ++i) {
            long long div = tmp[i] / base;
            tmp[i + 1] += div;
            tmp[i] -= div * base;
        }
        while (!tmp.empty() && tmp.back() == 0)
            tmp.pop_back();
        return vector<T>(tmp.begin(), tmp.end());
    }

    #ifdef BIGINT_USE_FFT
    static vector<int> _fft_mult_(const vector<int> &a, const vector<int> &b) {
        vector<int> ta(a.size() * 2), tb(b.size() * 2);
        static_assert(basen % 2 == 0, "basen has to be even");
        const static int M = pow(10, basen / 2);
        for (int i = 0; i < a.size(); ++i) {
            ta[i * 2] = a[i] % M;
            ta[i * 2 + 1] = a[i] / M;
        }
        for (int i = 0; i < b.size(); ++i) {
            tb[i * 2] = b[i] % M;
            tb[i * 2 + 1] = b[i] / M;
        }
        auto tc = fft::multiply(ta, tb);
        tc.resize(tc.size() / 2 * 2 + 10, 0);
        for (int i = 0; i + 1 < tc.size(); ++i) {
            tc[i + 1] += tc[i] / M;
            tc[i] %= M;
        }
        vector<int> res(tc.size() / 2);
        for (int i = 0; i < res.size(); ++i)
            res[i] = tc[i * 2] + tc[i * 2 + 1] * M;
        while (!res.empty() && res.back() == 0)
            res.pop_back();
        return res;
    }
    #endif

    static pair<vector<T>, vector<T>> _div_(vector<T> a, vector<T> b) {
        if (a.size() < b.size()) {
            return {{}, a};
        }
        vector<T> res;
        vector<T> c, c2;
        for (int i = (int)a.size() - b.size(); i >= 0; --i) {
            c.resize(b.size() + i);
            for (int j = 0; j < b.size(); ++j) {
                c[i + j] = b[j];
            }
            T L = 0, R = base;
            while (R - L > 1) {
                T C = (L + R) / 2;
                c2 = _mult_(c, {C});
                if (_comp_(a, c2)) {
                    R = C;
                } else {
                    L = C;
                }
            }
            c = _mult_(c, {L});
            _sub_(a, c);
            res.push_back(L);
        }
        reverse(res.begin(), res.end());
        return {res, a};
    }
};

string to_string(const Big &b) {
    if (b.v.empty()) return "0";
    string res;
    for (int i = (int)b.v.size() - 1; i >= 0; --i) {
        string t = to_string(b.v[i]);
        if (!res.empty())
            t = string(basen - t.size(), '0') + t;
        res += t;
    }
    if (b.minus)
        res.insert(res.begin(), '-');
    return res;
}

ostream &operator << (ostream &o, const Big &b) {
    return o << to_string(b);
};

istream &operator >> (istream &i, Big &b) {
    string s;
    i >> s;
    b = Big(s);
    return i;
}

Big gcd(Big a, Big b) {
    while (b != 0) {
        a %= b;
        swap(a, b);
    }
    return a;
}

const int P = 10;
const array<uint32_t, P> primes = {1038315533, 1070784149, 1152186131, 1226633593, 1383110039, 1811889307, 1863415583, 1871039267, 1893815057, 1925743987};

struct hash_my {
    size_t operator()(int x) const {
        x = ((x >> 16) ^ x) * 0x119de1f3;
        x = ((x >> 16) ^ x) * 0x119de1f3;
        x = (x >> 16) ^ x;
        return x;
    }

    size_t operator()(long long x) const {
        x = (x ^ (x >> 30)) * (0xbf58476d1ce4e5b9ll);
        x = (x ^ (x >> 27)) * (0x94d049bb133111ebll);
        x = x ^ (x >> 31);
        return x;
    }

    template<typename T, typename U>
    size_t operator()(const pair<T, U> &p) const {
        long long h1 = (*this)(p.first);
        long long h2 = (*this)(p.second);
        return (*this)(h1 ^ (h2 << 32) ^ (h2 >> 32));
    }
};

auto start_time = clock();

int main() {
    ios_base::sync_with_stdio(false); cin.tie(NULL);

    pow10[0] = 1;
    for (int i = 1; i < pow10.size(); ++i)
        pow10[i] = pow10[i - 1] * 10;

    // int t;
    // cin >> t;
    // while (t--) {
    //     Big a;
    //     int k;
    //     cin >> a >> k;
    //     Big b;
    //     cin >> b;
    //     a.modk(k);
    //     if (a != b) {
    //         cout << a << endl;
    //         cout << b << endl;
    //         show(a.v);
    //         show(b.v);
    //         assert(false);
    //     }
    //     cerr << "ok" << endl;
    // }

    map<array<uint32_t, P>, int> cnts;

    int n, k;
    cin >> n >> k;
    vector<Big> v;
    for (int i = 0; i < n; ++i) {
        string s;
        cin >> s;
        Big x(s);
        x.modk(k);
        v.pb(std::move(x));
    }

    show(v);

    Big b;
    Big mk(string(k, '9'));
    show(mk);
    Big b2;

    using namespace __gnu_pbds;
    vector<gp_hash_table<ll, int>> to;
    vector<int> res;
    to.eb();
    res.pb(0);

    // auto add_vec = [&](const vector<ll>& v) {
    //     int cur = 0;
    //     for (auto x : v) {
    //         auto it = to[cur].find(x);
    //         if (it != to[cur].end()) {
    //             cur = it->second;
    //         } else {
    //             int ccur = to.size();
    //             to.eb();
    //             res.pb(0);
    //             to[cur][x] = ccur;
    //             cur = ccur;
    //         }
    //     }
    //     res[cur]++;
    // };

    // auto ask_vec = [&](const vector<ll>& v) {
    //     int cur = 0;
    //     for (auto x : v) {
    //         auto it = to[cur].find(x);
    //         if (it != to[cur].end()) {
    //             cur = it->second;
    //         } else {
    //             return 0;
    //         }
    //     }
    //     return res[cur];
    // };

    vector<bool> is0;
    for (const auto& x : v) {
        is0.pb(count(x.v.begin(), x.v.end(), 0) == x.v.size());
    }
    int ans = 0;
    for (int i = 0; i < n; ++i) {
        if (!is0[i]) continue;
        for (int j = 0; j <= i; ++j) {
            if (!is0[j]) continue;
            for (int k = 0; k <= j; ++k) {
                ans += is0[k];
            }
        }
    }

    cerr << (double)(clock() - start_time) / CLOCKS_PER_SEC << endl;

    vector<array<uint32_t, P>> rems(n);
    for (int i = 0; i < n; ++i) {
        for (int pi = 0; pi < P; ++pi) {
            rems[i][pi] = v[i].modint(primes[pi]);
        }
    }

    array<uint32_t, P> remk;
    for (int pi = 0; pi < P; ++pi) {
        remk[pi] = mk.modint(primes[pi]);
    }

    for (int i = 0; i < n; ++i) {
        cnts[rems[i]]++;
        // add_vec(v[i].v);
        for (int j = i; j < n; ++j) {
            // b.v.assign(v[i].v.begin(), v[i].v.end());
            // b.minus = false;
            // b += v[j];
            // b.modk(k);
            // b2.v.assign(mk.v.begin(), mk.v.end());
            // b2.minus = false;
            // b2 -= b;
            // b2.modk(k);
            // b2.norm();

            array<uint32_t, P> rem = remk;
            for (int t = 0; t < P; ++t) {
                if (rem[t] < rems[i][t]) rem[t] += primes[t];
                rem[t] -= rems[i][t];
                if (rem[t] < rems[j][t]) rem[t] += primes[t];
                rem[t] -= rems[j][t];
            }
            {
                auto it = cnts.find(rem);
                if (it != cnts.end())
                    ans += it->second;
            }
            show(rems[i], rems[j], rem);
            for (int t = 0; t < P; ++t) {
                rem[t] += remk[t];
                if (rem[t] >= primes[t]) rem[t] -= primes[t];
            }
            show(rems[i], rems[j], rem);
            {
                auto it = cnts.find(rem);
                if (it != cnts.end())
                    ans += it->second;
            }
            // ans += ask_vec(b2.v);
            // {
            //     array<int, 10> rems;
            //     for (int pi = 0; pi < 10; ++pi) {
            //         rems[pi] = b2.modint(primes[pi]);
            //     }
            //     auto it = cnts.find(rems);
            //     if (it != cnts.end())
            //         ans += it->second;
            // }
        }
    }

    cout << ans << '\n';

    cerr << (double)(clock() - start_time) / CLOCKS_PER_SEC << endl;

    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3848kb

input:

4 1
0
1
10
17

output:

3

result:

ok 1 number(s): "3"

Test #2:

score: 0
Accepted
time: 20ms
memory: 4344kb

input:

500 859
7118711592236878297922359501613604144948355616986970837340677671376753603836852811886591300370143151943368529129749813118476151865844255212534355441611481420938483178075143062691345257288242460282715389758789648541099090735875617822348551942134616963557723055980260082230902505269975518146286...

output:

0

result:

ok 1 number(s): "0"

Test #3:

score: 0
Accepted
time: 103ms
memory: 13000kb

input:

500 17336
11871159223687829792235950161360414494835561698697083734067767137675360383685281188659130037014315194336852912974981311847615186584425521253435544161148142093848317807514306269134525728824246028271538975878964854109909073587561782234855194213461696355772305598026008223090250526997551814628...

output:

0

result:

ok 1 number(s): "0"

Test #4:

score: 0
Accepted
time: 58ms
memory: 13012kb

input:

500 1
751324443898124078584847834484321089092662321556147445230263526014359393841194947303407593948729802551881289193716611867931891257925091769456350249725997883453296895094445731130479434019358742162771547784250401546380268386074363779242500860317042151185119666027858022664683818314351285215150806...

output:

2327631

result:

ok 1 number(s): "2327631"

Test #5:

score: 0
Accepted
time: 57ms
memory: 13112kb

input:

500 2
408542968136435277974575411503179002415404345446801430469044749372949272333801248935236224652806667129749035002588943020176263162139056819871274824302889304493205266143688886696157147111754418731401856424401766968832165255416237731963027205324149660112574729610391396555581935236134531799950318...

output:

212002

result:

ok 1 number(s): "212002"

Test #6:

score: 0
Accepted
time: 78ms
memory: 13312kb

input:

500 11500
75411775796562109942642493394321873284995260953010112281856775261847503626737348402159485133662757032091519863427156582689971229143089317472838196453888261138079171290535429921921548971897026706656838415620603757605079012541561774699628665865662183868374645956694140356716037674688084770628...

output:

7675

result:

ok 1 number(s): "7675"

Test #7:

score: 0
Accepted
time: 94ms
memory: 13040kb

input:

500 11500
85355036663164764459816544518601485185320972076300982726542821424439713703229669576802138231401047471351087455159512255765325323540671792953715169122669767368905391325060775725733157611188832204902997772518104188947349204726490597030311894441123834099315122116302203972018409854605418988681...

output:

1070

result:

ok 1 number(s): "1070"

Test #8:

score: 0
Accepted
time: 1ms
memory: 4096kb

input:

1 11500
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999...

output:

1

result:

ok 1 number(s): "1"

Extra Test:

score: -3
Extra Test Failed : Runtime Error on 2

input:

3 8822
54306251634195846023516879906577593755825513792755775442947017499554654626661471720524208012575248737479709713799856599995531575091967474593437541693006587719070346995314750222170485067813283573996451951933684526463954516597956065818012465130929377586944506327326100207733415407488534641478072...

output:


result: