Submission #331231

#TimeUsernameProblemLanguageResultExecution timeMemory
331231AlexPop28Lucky Numbers (RMI19_lucky)C++11
100 / 100
36 ms11116 KiB
#include <bits/stdc++.h> #define dbg() cerr << #define name(x) (#x) << ": " << (x) << ' ' << using namespace std; const int MOD = (int)1e9 + 7; const int N = (int)1e5 + 10; template<class T> struct ModInt { T n; ModInt(bool n_) : n(n_) {} ModInt(T n_ = 0) : n(n_ % MOD) { while (n < 0) n += MOD; } ModInt operator+(const ModInt &other) const { return n + other.n; } ModInt operator-(const ModInt &other) const { return n - other.n; } ModInt operator*(const ModInt &other) const { return n * other.n; } ModInt& operator+=(const ModInt &other) { return *this = *this + other; } ModInt& operator-=(const ModInt &other) { return *this = *this - other; } ModInt& operator*=(const ModInt &other) { return *this = *this * other; } T operator()() { return n; } }; using Int = ModInt<int64_t>; Int ways[N]; Int Ways(int n) { if (n >= 0) return ways[n]; return Int((int64_t)0); } Int operator*(const bool &x, const Int &y) { if (x) return y; return Int((int64_t)0); } struct Node { int len; Int dp, dp1, dp3, dp13; // excluding current interval bool _dp, _dp1, _dp3, _dp13; // current interval Node(int64_t val = 0) { len = 1; dp = val; dp1 = val > 1; dp3 = val > 3; dp13 = false; _dp = true; _dp1 = val == 1; _dp3 = val == 3; _dp13 = false; } Node operator+(const Node &other) const { Node ret; ret.len = len + other.len; ret.dp = dp * Ways(other.len) - dp1 * Ways(other.len - 1) + _dp * other.dp - _dp1 * other.dp3; ret.dp1 = dp * Ways(other.len - 1) - dp1 * Ways(other.len - 2) + _dp * other.dp1 - _dp1 * other.dp13; ret.dp3 = dp3 * Ways(other.len) - dp13 * Ways(other.len - 1) + _dp3 * other.dp - _dp13 * other.dp3; ret.dp13 = dp3 * Ways(other.len - 1) - dp13 * Ways(other.len - 2) + _dp3 * other.dp1 - _dp13 * other.dp13; ret._dp = _dp && other._dp && (!_dp1 || !other._dp3); ret._dp1 = ret._dp && other._dp1; ret._dp3 = ret._dp && _dp3; ret._dp13 = ret._dp && _dp3 && other._dp1; return ret; } Int Get() { return dp + _dp; } }; struct SegmTree { int n; vector<Node> t; SegmTree(const string &s) : n(s.size()), t(2 * n) { for (int i = 0; i < n; ++i) t[i + n] = Node(s[i] - '0'); for (int i = n - 1; i >= 1; --i) t[i] = t[2 * i] + t[2 * i + 1]; } void Update(int pos, int val) { for (t[pos += n] = Node(val); pos /= 2; ) t[pos] = t[2 * pos] + t[2 * pos + 1]; } Node Query(int l, int r) { Node ans_l, ans_r; bool fst_l = true, fst_r = true; for (l += n, r += n; l < r; l /= 2, r /= 2) { if (l & 1) { if (fst_l) ans_l = t[l++]; else ans_l = ans_l + t[l++]; fst_l = false; } if (r & 1) { if (fst_r) ans_r = t[--r]; else ans_r = t[--r] + ans_r; fst_r = false; } } if (fst_l) return ans_r; if (fst_r) return ans_l; return ans_l + ans_r; } }; int main() { ios::sync_with_stdio(0); cin.tie(0); ways[0] = (int64_t)1; for (int i = 1; i < N; ++i) { ways[i] = ways[i - 1] * Int((int64_t)10); if (i - 2 >= 0) ways[i] -= ways[i - 2]; } // string s = "14"; // SegmTree st(s); // cout << st.Query(0, 2).Get()() << endl; int n, q; cin >> n >> q; cin.get(); string s; getline(cin, s); assert(n == (int)s.length()); SegmTree st(s); cout << st.Query(0, n).Get()() << '\n'; while (q--) { int t; cin >> t; if (t == 1) { int l, r; cin >> l >> r; cout << st.Query(l - 1, r).Get()() << '\n'; } else { int pos, dig; cin >> pos >> dig; st.Update(pos - 1, dig); } } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...