Submission #218012

#TimeUsernameProblemLanguageResultExecution timeMemory
218012tincamateiLucky Numbers (RMI19_lucky)C++14
100 / 100
199 ms10488 KiB
/** * user: tinca-6db * fname: Matei * lname: Tinca * task: lucky * score: 100.0 * date: 2019-10-10 09:19:09.769672 */ #include <bits/stdc++.h> using namespace std; const int MOD = 1000000007; const int MAX_N = 100000; struct IntMod { int val; IntMod():val(0) {} IntMod(int x):val(x % MOD) {} IntMod operator+(IntMod x) { if(x.val + val >= MOD) return x.val + val - MOD; return x.val + val; } IntMod operator*(IntMod x) { return (long long)x.val * val % MOD; } IntMod operator+(int x) { return (*this) + IntMod(x); } IntMod operator*(int x) { return (*this) * IntMod(x); } IntMod operator-(IntMod x) { return (*this) + (MOD - x.val); } IntMod operator-(int x) { return (*this) - IntMod(x); } }; // cate numere bune de forma a1a2...aN exista? IntMod _goodcnt[1+MAX_N+1], *goodcnt = _goodcnt + 1; struct AintNode { int size; IntMod cntgood, cntgood1, cntgood3, cntgood31; bool isgood, isgood1, isgood3, isgood31; }; // cntgood = numar chestii bune pe interval // cntgood1 = numar chestii bune pe interval care se termina cu 1 // cntgood3 = numar chestii bune pe interval care incep cu 3 // cntgood31 = numar chestii bune pe interval care incep cu 3 si se termina cu 1 AintNode combine(AintNode a, AintNode b) { AintNode rez; rez.isgood = a.isgood && b.isgood && !(a.isgood1 && b.isgood3); rez.isgood1 = b.isgood1 && a.isgood && !(a.isgood1 && b.isgood3); rez.isgood3 = a.isgood3 && b.isgood && !(a.isgood1 && b.isgood3); rez.isgood31 = a.isgood3 && b.isgood1 && !(a.isgood1 && b.isgood3); rez.cntgood = (a.cntgood - a.isgood) * goodcnt[b.size] + b.cntgood * a.isgood - (a.cntgood1 - a.isgood1) * goodcnt[b.size - 1] - b.cntgood3 * a.isgood1; rez.cntgood1 = (a.cntgood - a.isgood) * goodcnt[b.size - 1] + b.cntgood1 * a.isgood - (a.cntgood1 - a.isgood1) * goodcnt[b.size - 2] - b.cntgood31 * a.isgood1; rez.cntgood3 = (a.cntgood3 - a.isgood3) * goodcnt[b.size] + b.cntgood * a.isgood3 - (a.cntgood31 - a.isgood31) * goodcnt[b.size - 1] - b.cntgood3 * a.isgood31; rez.cntgood31 = (a.cntgood3 - a.isgood3) * goodcnt[b.size - 1] + b.cntgood1 * a.isgood3 - (a.cntgood31 - a.isgood31) * goodcnt[b.size - 2] - b.cntgood31 * a.isgood31; rez.size = a.size + b.size; return rez; } AintNode aint[1+4*MAX_N]; void update(int poz, AintNode val, int l = 1, int r = MAX_N, int nod = 1) { if(r < poz || poz < l) return; if(l == r) aint[nod] = val; else { int mid = (l + r) / 2; update(poz, val, l, mid, 2 * nod); update(poz, val, mid + 1, r, 2 * nod + 1); aint[nod] = combine(aint[2 * nod], aint[2 * nod + 1]); } } AintNode query(int i, int j, int l = 1, int r = MAX_N, int nod = 1) { if(i <= l && r <= j) return aint[nod]; else { int mid = (l + r) / 2; if(i > mid) return query(i, j, mid + 1, r, 2 * nod + 1); else if(j <= mid) return query(i, j, l, mid, 2 * nod); else return combine(query(i, j, l, mid, 2 * nod), query(i, j, mid + 1, r, 2 * nod + 1)); } } void dfs(int nod = 1, int l = 1, int r = MAX_N) { printf("RANGE: %d %d->%d\n", l, r, nod); printf("isgood: %d %d %d %d", aint[nod].isgood, aint[nod].isgood1, aint[nod].isgood3, aint[nod].isgood31); printf("cntgood: %d %d %d %d\n", aint[nod].cntgood.val, aint[nod].cntgood1.val, aint[nod].cntgood3.val, aint[nod].cntgood31.val); int mid = (l + r) / 2; if(l < r) { dfs(2 * nod, l, mid); dfs(2 * nod + 1, mid + 1, r); } } // AintNode = {size, cntgood, cntgood1, cntgood3, cntgood31, isgood, isgood1, isgood3, isgood31} AintNode updDigit[10] = { {1, IntMod(1), IntMod(0), IntMod(0), IntMod(0), true, false, false, false}, // 0 {1, IntMod(2), IntMod(1), IntMod(0), IntMod(0), true, true , false, false}, // 1 {1, IntMod(3), IntMod(1), IntMod(0), IntMod(0), true, false, false, false}, // 2 {1, IntMod(4), IntMod(1), IntMod(1), IntMod(0), true, false, true , false}, // 3 {1, IntMod(5), IntMod(1), IntMod(1), IntMod(0), true, false, false, false}, // 4 {1, IntMod(6), IntMod(1), IntMod(1), IntMod(0), true, false, false, false}, // 5 {1, IntMod(7), IntMod(1), IntMod(1), IntMod(0), true, false, false, false}, // 6 {1, IntMod(8), IntMod(1), IntMod(1), IntMod(0), true, false, false, false}, // 7 {1, IntMod(9), IntMod(1), IntMod(1), IntMod(0), true, false, false, false}, // 8 {1, IntMod(10),IntMod(1), IntMod(1), IntMod(0), true, false, false, false} // 9 }; char getChar(FILE *fin) { char ch = fgetc(fin); while(!isdigit(ch)) ch = fgetc(fin); return ch; } int main() { int N, Q; goodcnt[0] = 1; for(int i = 1; i <= MAX_N; ++i) goodcnt[i] = goodcnt[i - 1] * 10 - goodcnt[i - 2]; scanf("%d%d", &N, &Q); for(int i = 1; i <= N; ++i) update(i, updDigit[getChar(stdin) - '0']); printf("%d\n", query(1, N).cntgood.val); for(int i = 0; i < Q; ++i) { int t, x, y; scanf("%d%d%d", &t, &x, &y); if(t == 2) update(x, updDigit[y]); else printf("%d\n", query(x, y).cntgood.val); } return 0; }

Compilation message (stderr)

lucky.cpp: In function 'int main()':
lucky.cpp:146:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d%d", &N, &Q);
  ~~~~~^~~~~~~~~~~~~~~~
lucky.cpp:153:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d%d%d", &t, &x, &y);
   ~~~~~^~~~~~~~~~~~~~~~~~~~~~
#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...