제출 #1119643

#제출 시각아이디문제언어결과실행 시간메모리
1119643MateiKing80Lucky Numbers (RMI19_lucky)C++17
14 / 100
11 ms4436 KiB
#include <bits/stdc++.h> using namespace std; const int mod = 1e9 + 7, N = 1e5; long long p10[N + 5], p10fata[N + 5], p10spate[N + 5], p10fataspate[N + 5]; struct nod { long long nrtotal = 1, fata = 0, spate = 0, fataspate = 0; int cifrafata = 0, cifraspate = 0, are13 = 0, lg = 1; }; nod aint[4 * N + 5]; void print(nod x) { cout << x.nrtotal << " " << x.fata << " " << x.spate << " " << x.fataspate << '\n'; cout << x.cifrafata << " " << x.cifraspate << " " << x.are13 << " " << x.lg << '\n'; cout << '\n'; } nod cif(int x) { nod a; a.nrtotal = x + 1; if(x >= 3) a.fata = 1; if(x >= 1) a.spate = 1; a.fataspate = 0; a.cifrafata = x; a.cifraspate = x; a.are13 = 0; a.lg = 1; return a; } nod join(nod a, nod b) { nod c; c.cifrafata = a.cifrafata; c.cifraspate = b.cifraspate; if(a.cifraspate == 1 && b.cifrafata == 3) c.are13 = 1; else c.are13 = (a.are13 | b.are13); c.lg = a.lg + b.lg; if(!a.are13) { a.nrtotal --; if(a.cifraspate == 1) a.spate --; if(a.cifrafata == 3) a.fata --; if(a.cifrafata == 3 && a.cifraspate == 1) a.fataspate --; } if(a.are13) c.nrtotal = a.nrtotal * p10[b.lg] - a.spate * p10fata[b.lg]; else { if(a.cifraspate == 1) c.nrtotal = a.nrtotal * p10[b.lg] - a.spate * p10fata[b.lg] + b.nrtotal - b.fata; else c.nrtotal = a.nrtotal * p10[b.lg] - a.spate * p10fata[b.lg] + b.nrtotal; } c.nrtotal = (c.nrtotal % mod + mod) % mod; if(a.are13) c.fata = a.fata * p10[b.lg] - a.fataspate * p10fata[b.lg]; else { if(a.cifraspate == 1) c.fata = a.fata * p10[b.lg] - a.fataspate * p10fata[b.lg] + b.nrtotal - b.fata; else c.fata = a.fata * p10[b.lg] - a.fataspate * p10fata[b.lg] + b.nrtotal; } c.fata = (c.fata % mod + mod) % mod; if(a.are13) c.spate = a.nrtotal * p10spate[b.lg] - a.spate * p10fataspate[b.lg]; else { if(a.cifraspate == 1) c.spate = a.nrtotal * p10spate[b.lg] - a.spate * p10fataspate[b.lg] + b.spate - b.fataspate; else c.spate = a.nrtotal * p10spate[b.lg] - a.spate * p10fataspate[b.lg] + b.spate; } c.spate = (c.spate % mod + mod) % mod; if(a.are13) c.fataspate = a.fata * p10spate[b.lg] - a.fataspate * p10fataspate[b.lg]; else { if(a.cifraspate == 1) c.fataspate = a.fata * p10spate[b.lg] - a.fataspate * p10fataspate[b.lg] + b.spate - b.fataspate; else c.fataspate = a.fata * p10spate[b.lg] - a.fataspate * p10fataspate[b.lg] + b.spate; } c.fataspate = (c.fataspate % mod + mod) % mod; // print(a); // print(b); // print(c); // cout << '\n'; return c; } #define mid (st + dr) / 2 void update(int pos, int st, int dr, int l, int val) { if(st == dr) { aint[pos] = cif(val); return; } if(l <= mid) update(2 * pos, st, mid, l, val); else update(2 * pos + 1, mid + 1, dr, l, val); aint[pos] = join(aint[2 * pos], aint[2 * pos + 1]); } nod query(int pos, int st, int dr, int l, int r) { if(l <= st && dr <= r) return aint[pos]; if(r <= mid) return query(2 * pos, st, mid, l, r); if(mid < l) return query(2 * pos + 1, mid + 1, dr, l, r); return join(query(2 * pos, st, mid, l, r), query(2 * pos + 1, mid + 1, dr, l, r)); } int main() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); p10[0] = 1; p10[1] = 10; p10fata[1] = 1; p10spate[1] = 1; p10fataspate[1] = 0; for(int i = 2; i <= N; i ++) { p10[i] = (p10[i - 1] * 10 - p10fata[i - 1] + mod) % mod; p10fata[i] = p10[i - 1]; p10spate[i] = p10[i - 1]; p10fataspate[i] = p10[i - 2]; } int n, q; cin >> n >> q; string s; cin >> s; for(int i = 1; i <= n; i ++) update(1, 1, n, i, s[i - 1] - '0'); cout << query(1, 1, n, 1, n).nrtotal << '\n'; for(int i = 0; i < q; i ++) { int t, l, r; cin >> t >> l >> r; if(t == 1) cout << query(1, 1, n, l, r).nrtotal << '\n'; else update(1, 1, n, l, r); } } /* putem face un aint in care sa tinem in stanga nr de numere pe care le putem face fara 13 in dreapta la fel si mai tinem cate nr fara 13 putem face a.i. ultima cifra sa fie 1 si cate nr fara 13 putem face a.i. ultima cifra sa fie 3 si cred ca ne trebuie si cate putem face a.i. prima cifra sa fie 1 si ultima fie 3 also ne trebuie o precalculare pentru cate numere pana in 10^x nu au 13 cate numere pana in 10^x nu au 13 si au 1 prima cifra si cate numere pana in 10^x nu au 13 si au 3 ultima cifra fata inseamna sa aiba prima cifra 3 dar nicaieri 13 spate inseamna sa aiba prima cifra 1 dar nicaieri 13 c.nrtotal daca a are deja 13 a.nrtotal * p10[b.nrcif] - a.spate * p10fata[b.nrcif]; altfel daca a are ultima cifra 1 a.nrtotal * p10[b.nrcif] - a.spate * p10fata[b.nrcif] + b.nrtotal - b.fata altfel a.nrtotal * p10[b.nrcif] - a.spate * p10fata[b.nrcif] + b.nrtotal c.fata daca a are deja 13 a.fata * p10[b.nrcif] - a.spate * p10fata[b.nrcif]; altfel daca a are ultima cifra 1 a.fata * p10[b.nrcif] - a.spate * p10fata[b.nrcif] + b.nrtotal - b.fata altfel a.fata * p10[b.nrcif] - a.spate * p10fata[b.nrcif] + b.nrtotal c.spate daca a are deja 13 a.nrtotal * p10spate[b.nrcif] - a.spate * p10fataspate[b.nrcif]; altfel daca a are ultima cifra 1 a.nrtotal * p10spate[b.nrcif] - a.spate * p10fataspate[b.nrcif] + b.spate - b.fataspate altfel a.nrtotal * p10spate[b.nrcif] - a.spate * p10fataspate[b.nrcif] + b.spate c.fataspate daca a are deja 13 a.fata * p10spate[b.nrcif] - a.fataspate * p10fataspate[b.nrcif]; altfel daca a are ultima cifra 1 a.fata * p10spate[b.nrcif] - a.fataspate * p10fataspate[b.nrcif] + b.spate - b.fataspate altfel a.fata * p10spate[b.nrcif] - a.fataspate * p10fataspate[b.nrcif] + b.spate */
#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...