Submission #492788

# Submission time Handle Problem Language Result Execution time Memory
492788 2021-12-08T22:15:15 Z maksim1744 Lucky Numbers (RMI19_lucky) C++17
64 / 100
87 ms 17528 KB
/*
    author:  Maksim1744
    created: 09.12.2021 00:29:14
*/

#include "bits/stdc++.h"

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)
#endif

namespace mint_ns {
template<auto P>
struct Modular {
    using value_type = decltype(P);
    value_type value;

    Modular(long long k = 0) : value(norm(k)) {}

    friend Modular<P>& operator += (      Modular<P>& n, const Modular<P>& m) { n.value += m.value; if (n.value >= P) n.value -= P; return n; }
    friend Modular<P>  operator +  (const Modular<P>& n, const Modular<P>& m) { Modular<P> r = n; return r += m; }

    friend Modular<P>& operator -= (      Modular<P>& n, const Modular<P>& m) { n.value -= m.value; if (n.value < 0)  n.value += P; return n; }
    friend Modular<P>  operator -  (const Modular<P>& n, const Modular<P>& m) { Modular<P> r = n; return r -= m; }
    friend Modular<P>  operator -  (const Modular<P>& n)                      { return Modular<P>(-n.value); }

    friend Modular<P>& operator *= (      Modular<P>& n, const Modular<P>& m) { n.value = n.value * 1ll * m.value % P; return n; }
    friend Modular<P>  operator *  (const Modular<P>& n, const Modular<P>& m) { Modular<P> r = n; return r *= m; }

    friend Modular<P>& operator /= (      Modular<P>& n, const Modular<P>& m) { return n *= m.inv(); }
    friend Modular<P>  operator /  (const Modular<P>& n, const Modular<P>& m) { Modular<P> r = n; return r /= m; }

    Modular<P>& operator ++ (   ) { return *this += 1; }
    Modular<P>& operator -- (   ) { return *this -= 1; }
    Modular<P>  operator ++ (int) { Modular<P> r = *this; *this += 1; return r; }
    Modular<P>  operator -- (int) { Modular<P> r = *this; *this -= 1; return r; }

    friend bool operator == (const Modular<P>& n, const Modular<P>& m) { return n.value == m.value; }
    friend bool operator != (const Modular<P>& n, const Modular<P>& m) { return n.value != m.value; }

    explicit    operator       int() const { return value; }
    explicit    operator      bool() const { return value; }
    explicit    operator long long() const { return value; }

    constexpr static value_type mod()      { return     P; }

    value_type norm(long long k) {
        if (!(-P <= k && k < P)) k %= P;
        if (k < 0) k += P;
        return k;
    }

    Modular<P> inv() const {
        value_type a = value, b = P, x = 0, y = 1;
        while (a != 0) { value_type k = b / a; b -= k * a; x -= k * y; swap(a, b); swap(x, y); }
        return Modular<P>(x);
    }
};
template<auto P> Modular<P> pow(Modular<P> m, long long p) {
    Modular<P> r(1);
    while (p) {
        if (p & 1) r *= m;
        m *= m;
        p >>= 1;
    }
    return r;
}

template<auto P> ostream& operator << (ostream& o, const Modular<P>& m) { return o << m.value; }
template<auto P> istream& operator >> (istream& i,       Modular<P>& m) { long long k; i >> k; m.value = m.norm(k); return i; }
template<auto P> string   to_string(const Modular<P>& m) { return to_string(m.value); }

using Mint = Modular<1000000007>;
// using Mint = Modular<998244353>;
// using Mint = long double;

vector<Mint> f, fi;
void init_C(int n) {
    f.assign(n, 1); fi.assign(n, 1);
    for (int i = 2; i < n; ++i) f[i] = f[i - 1] * i;
    fi.back() = Mint(1) / f.back();
    for (int i = n - 2; i >= 0; --i) fi[i] = fi[i + 1] * (i + 1);
}
Mint C(int n, int k) {
    if (k < 0 || k > n) return 0;
    else return f[n] * fi[k] * fi[n - k];
}
}
using namespace mint_ns;

template<typename T, int N>
struct Matrix {
    array<array<T, N>, N> m;

    Matrix() {
        for (int i = 0; i < N; ++i) {
            for (int j = 0; j < N; ++j) {
                m[i][j] = 0;
            }
        }
    }
    Matrix(std::initializer_list<std::initializer_list<T>> s) {
        int i = 0;
        for (auto it = s.begin(); it != s.end(); ++it) {
            int j = 0;
            for (auto it2 = it->begin(); it2 != it->end(); ++it2) {
                m[i][j] = *it2;
                ++j;
            }
            ++i;
        }
    }

    static Matrix E() {
        Matrix e;
        for (int i = 0; i < N; ++i) {
            e[i][i] = 1;
        }
        return e;
    }

    array<T, N> &operator[](int i) {
        return m[i];
    }

    const array<T, N> &operator[](int i) const {
        return m[i];
    }

    Matrix operator * (const Matrix &b) const {
        Matrix c;
        for (int i = 0; i < N; ++i) {
            for (int j = 0; j < N; ++j) {
                for (int k = 0; k < N; ++k) {
                    c[i][k] += m[i][j] * b[j][k];
                }
            }
        }
        return c;
    }

    Matrix &operator *= (const Matrix &other) {
        *this = (*this) * other;
        return *this;
    }

    Matrix &operator *= (const T &x) {
        for (int i = 0; i < N; ++i) {
            for (int j = 0; j < N; ++j) {
                m[i][j] *= x;
            }
        }
        return *this;
    }
    Matrix operator * (const T &x) const {
        Matrix a = *this;
        a *= x;
        return a;
    }

    Matrix &operator /= (const T &x) {
        T inv = T(1) / x;
        for (int i = 0; i < N; ++i) {
            for (int j = 0; j < N; ++j) {
                m[i][j] *= inv;
            }
        }
        return *this;
    }
    Matrix operator / (const T &x) const {
        Matrix a = *this;
        a /= x;
        return a;
    }

    Matrix &operator += (const Matrix &other) {
        for (int i = 0; i < N; ++i) {
            for (int j = 0; j < N; ++j) {
                m[i][j] += other[i][j];
            }
        }
        return *this;
    }
    Matrix operator + (const Matrix &other) const {
        Matrix a = *this;
        a += other;
        return a;
    }

    Matrix &operator -= (const Matrix &other) {
        for (int i = 0; i < N; ++i) {
            for (int j = 0; j < N; ++j) {
                m[i][j] -= other[i][j];
            }
        }
        return *this;
    }
    Matrix operator - (const Matrix &other) const {
        Matrix a = *this;
        a -= other;
        return a;
    }
};

template<typename T, int N>
Matrix<T, N> pow(Matrix<T, N> m, ll p) {
    Matrix<T, N> res = Matrix<T, N>::E();
    while (p) {
        if (p & 1) res *= m;
        m *= m;
        p >>= 1;
    }
    return res;
}

using M = Matrix<Mint, 4>;

int get_ind(int num, int b) {
    return (num == 1) + (b) * 2;
}

struct item {
    M m;

    template<typename T>
    void init(const T &t, int l, int r) {
        for (int prev = 0; prev < 2; ++prev) {
            for (int next = 0; next < 10; ++next) {
                if (prev == 1 && next == 3) continue;
                if (next <= t) {
                    m[get_ind(next, next == t)][get_ind(prev, 1)]++;
                }
                m[get_ind(next, 0)][get_ind(prev, 0)]++;
            }
        }
    }

    void update(const item &first, const item &second, int l, int r) {
        m = second.m * first.m;
    }

    static item merge(const item &first, const item &second, int l, int r) {
        item res;
        res.update(first, second, l, r);  // careful with different lengths
        return res;
    }
};

string to_string(const item &i) {
    stringstream ss;
    ss << "[" << "]";
    return ss.str();
}
ostream& operator << (ostream &o, const item &i) {
    return o << to_string(i);
}

struct segtree {
    vector<item> tree;
    int n = 1;

    segtree(int n = 1) : n(n) {
        tree.resize(1 << (__lg(max(1, n - 1)) + 2));
    }

    template<typename T>
    void build(const vector<T> &v, int i, int l, int r) {
        if (l == r) {
            tree[i].init(v[l], l, r);
            return;
        }
        int m = (l + r) >> 1;
        build(v, i * 2 + 1, l, m);
        build(v, i * 2 + 2, m + 1, r);
        tree[i].update(tree[i * 2 + 1], tree[i * 2 + 2], l, r);
    }

    template<typename T>
    void build(const vector<T> &v) {
        n = v.size();
        tree.resize(1 << (__lg(max(1, n - 1)) + 2));
        build(v, 0, 0, n - 1);
    }

    item ask(int l, int r, int i, int vl, int vr) {
        if (l == vl && r == vr) {
            return tree[i];
        }
        int m = (vl + vr) >> 1;
        if (r <= m) {
            return ask(l, r, i * 2 + 1, vl, m);
        } else if (m < l) {
            return ask(l, r, i * 2 + 2, m + 1, vr);
        } else {
            return item::merge(ask(l, m, i * 2 + 1, vl, m), ask(m + 1, r, i * 2 + 2, m + 1, vr), l, r);
        }
    }

    item ask(int l, int r) {
        l = max(l, 0); r = min(r, n - 1);
        if (l > r) return item();
        return ask(l, r, 0, 0, n - 1);
    }

    template<typename T>
    void set(int ind, const T &t) {
        static array<pair<int, int>, 30> st;
        int l = 0, r = n - 1, i = 0;
        int ptr = -1;
        while (l != r) {
            st[++ptr] = {l, r};
            int m = (l + r) >> 1;
            if (ind <= m) {
                i = i * 2 + 1;
                r = m;
            } else {
                i = i * 2 + 2;
                l = m + 1;
            }
        }
        tree[i].init(t, l, r);
        while (i != 0) {
            i = (i - 1) / 2;
            tree[i].update(tree[i * 2 + 1], tree[i * 2 + 2], st[ptr].first, st[ptr].second);
            --ptr;
        }
    }
};

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

    int n, q;
    cin >> n >> q;
    string s;
    cin >> s;

    vector<int> v;
    for (char c : s)
        v.pb(c - '0');
    segtree tree(n);
    tree.build(v);

    auto que = [&](int l, int r) {
        M m = tree.ask(l, r).m;
        Mint ans = 0;
        for (int i = 0; i < 4; ++i)
            ans += m[i][2];
        cout << ans << '\n';
    };

    que(0, n - 1);

    while (q--) {
        int t;
        cin >> t;
        if (t == 1) {
            int l, r;
            cin >> l >> r;
            --l; --r;
            que(l, r);
        } else {
            int ind, c;
            cin >> ind >> c;
            --ind;
            tree.set(ind, c);
        }
    }


    return 0;
}
# Verdict Execution time Memory Grader output
1 Correct 0 ms 204 KB Output is correct
2 Correct 0 ms 204 KB Output is correct
3 Correct 0 ms 204 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 0 ms 204 KB Output is correct
2 Correct 0 ms 204 KB Output is correct
3 Correct 0 ms 204 KB Output is correct
4 Correct 0 ms 204 KB Output is correct
5 Correct 0 ms 204 KB Output is correct
6 Correct 1 ms 204 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 37 ms 1428 KB Output is correct
2 Correct 31 ms 2508 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 37 ms 1428 KB Output is correct
2 Correct 31 ms 2508 KB Output is correct
3 Correct 63 ms 17364 KB Output is correct
4 Correct 65 ms 17528 KB Output is correct
5 Correct 70 ms 17412 KB Output is correct
6 Correct 87 ms 17472 KB Output is correct
7 Correct 78 ms 17480 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 0 ms 204 KB Output is correct
2 Correct 0 ms 204 KB Output is correct
3 Correct 0 ms 204 KB Output is correct
4 Correct 0 ms 204 KB Output is correct
5 Correct 0 ms 204 KB Output is correct
6 Correct 1 ms 204 KB Output is correct
7 Correct 37 ms 1428 KB Output is correct
8 Correct 31 ms 2508 KB Output is correct
9 Incorrect 24 ms 1448 KB Output isn't correct
10 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 0 ms 204 KB Output is correct
2 Correct 0 ms 204 KB Output is correct
3 Correct 0 ms 204 KB Output is correct
4 Correct 0 ms 204 KB Output is correct
5 Correct 0 ms 204 KB Output is correct
6 Correct 1 ms 204 KB Output is correct
7 Correct 37 ms 1428 KB Output is correct
8 Correct 31 ms 2508 KB Output is correct
9 Correct 63 ms 17364 KB Output is correct
10 Correct 65 ms 17528 KB Output is correct
11 Correct 70 ms 17412 KB Output is correct
12 Correct 87 ms 17472 KB Output is correct
13 Correct 78 ms 17480 KB Output is correct
14 Incorrect 24 ms 1448 KB Output isn't correct
15 Halted 0 ms 0 KB -