#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 time |
Memory |
Grader output |
1 |
Correct |
2 ms |
1132 KB |
Output is correct |
2 |
Correct |
2 ms |
1132 KB |
Output is correct |
3 |
Correct |
3 ms |
1132 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
2 ms |
1132 KB |
Output is correct |
2 |
Correct |
2 ms |
1132 KB |
Output is correct |
3 |
Correct |
3 ms |
1132 KB |
Output is correct |
4 |
Correct |
2 ms |
1132 KB |
Output is correct |
5 |
Correct |
2 ms |
1132 KB |
Output is correct |
6 |
Correct |
2 ms |
1132 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
13 ms |
2028 KB |
Output is correct |
2 |
Correct |
15 ms |
2284 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
13 ms |
2028 KB |
Output is correct |
2 |
Correct |
15 ms |
2284 KB |
Output is correct |
3 |
Correct |
24 ms |
9068 KB |
Output is correct |
4 |
Correct |
29 ms |
9068 KB |
Output is correct |
5 |
Correct |
28 ms |
10092 KB |
Output is correct |
6 |
Correct |
30 ms |
11116 KB |
Output is correct |
7 |
Correct |
32 ms |
11116 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
2 ms |
1132 KB |
Output is correct |
2 |
Correct |
2 ms |
1132 KB |
Output is correct |
3 |
Correct |
3 ms |
1132 KB |
Output is correct |
4 |
Correct |
2 ms |
1132 KB |
Output is correct |
5 |
Correct |
2 ms |
1132 KB |
Output is correct |
6 |
Correct |
2 ms |
1132 KB |
Output is correct |
7 |
Correct |
13 ms |
2028 KB |
Output is correct |
8 |
Correct |
15 ms |
2284 KB |
Output is correct |
9 |
Correct |
12 ms |
2028 KB |
Output is correct |
10 |
Correct |
15 ms |
2284 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
2 ms |
1132 KB |
Output is correct |
2 |
Correct |
2 ms |
1132 KB |
Output is correct |
3 |
Correct |
3 ms |
1132 KB |
Output is correct |
4 |
Correct |
2 ms |
1132 KB |
Output is correct |
5 |
Correct |
2 ms |
1132 KB |
Output is correct |
6 |
Correct |
2 ms |
1132 KB |
Output is correct |
7 |
Correct |
13 ms |
2028 KB |
Output is correct |
8 |
Correct |
15 ms |
2284 KB |
Output is correct |
9 |
Correct |
24 ms |
9068 KB |
Output is correct |
10 |
Correct |
29 ms |
9068 KB |
Output is correct |
11 |
Correct |
28 ms |
10092 KB |
Output is correct |
12 |
Correct |
30 ms |
11116 KB |
Output is correct |
13 |
Correct |
32 ms |
11116 KB |
Output is correct |
14 |
Correct |
12 ms |
2028 KB |
Output is correct |
15 |
Correct |
15 ms |
2284 KB |
Output is correct |
16 |
Correct |
24 ms |
9068 KB |
Output is correct |
17 |
Correct |
24 ms |
9068 KB |
Output is correct |
18 |
Correct |
29 ms |
9964 KB |
Output is correct |
19 |
Correct |
31 ms |
10988 KB |
Output is correct |
20 |
Correct |
36 ms |
10988 KB |
Output is correct |