Submission #1328226

#TimeUsernameProblemLanguageResultExecution timeMemory
1328226horiaboeriuLucky Numbers (RMI19_lucky)C++20
100 / 100
34 ms12708 KiB
#include <bits/stdc++.h>

using namespace std;
const int MAXN = 100000;
const int MAXP = 131072;
const int MOD = 1e9 + 7;
const int MAXC = 9;
struct segTree {
    //primul este ca sa stiu daca 0 - nu incepe cu 3, 1 - incepe cu 3
    //al doilea este ca sa stiu daca 0 - nu se termina cu 1, 1 - se termina cu 1
    int countEq[2][2], countLess[2][2], countAll[2][2];//countAll ar fi putut sa fie precalculat
} v[2 * MAXP];
void buildCif(int nod, int cif) {
    int a, b, x, rez2;
    for (a = 0; a < 2; a++) {
        for (b = 0; b < 2; b++) {
            v[nod].countEq[a][b] = v[nod].countAll[a][b] = v[nod].countLess[a][b] = 0;//mai intai le resetez ca poate am avut alta cifra pana acum aici
            for (x = 0; x <= MAXC; x++) {
                rez2 = 0;
                if (a == (x == 3) && b == (x == 1)) {
                    rez2 = 1;
                }
                if (x < cif) {
                    v[nod].countLess[a][b] += rez2;
                }
                v[nod].countAll[a][b] += rez2;
            }
        }
    }
    v[nod].countEq[(cif == 3)][(cif == 1)] = 1;
}
segTree join(segTree st, segTree dr) {
    segTree rez;
    int a, b, c, d;
    for (a = 0; a < 2; a++) {
        for (d = 0; d < 2; d++) {
            rez.countAll[a][d] = rez.countEq[a][d] = rez.countLess[a][d] = 0;//il initializez cu 0
        }
    }
    for (b = 0; b < 2; b++) {
        for (c = 0; c < 2; c++) {
            if (b + c < 2) {//daca sunt amandoi 1 inseamna ca se formeaza un 13 si nu ar trebui
                for (a = 0; a < 2; a++) {
                    for (d = 0; d < 2; d++) {
                        rez.countAll[a][d] = (rez.countAll[a][d] + (long long)st.countAll[a][b] * dr.countAll[c][d]) % MOD;
                        rez.countEq[a][d] = (rez.countEq[a][d] + (long long)st.countEq[a][b] * dr.countEq[c][d]) % MOD;
                        rez.countLess[a][d] = (rez.countLess[a][d] + (long long)st.countLess[a][b] * dr.countAll[c][d] + (long long)st.countEq[a][b] * dr.countLess[c][d]) % MOD;
                    }
                }
            }
        }
    }
    return rez;
}
void build(int nod, int st, int dr) {
    int mid;
    char ch;
    if (st == dr) {
        ch = fgetc(stdin) - '0';
        buildCif(nod, ch);
    } else {
        mid = (st + dr) / 2;
        build(2 * nod, st, mid);
        build(2 * nod + 1, mid + 1, dr);
        v[nod] = join(v[2 * nod], v[2 * nod + 1]);
    }
}
void update(int nod, int st, int dr, int poz, int val) {
    int mid;
    if (st == dr) {
        buildCif(nod, val);
    } else {
        mid = (st + dr) / 2;
        if (poz <= mid) {
            update(2 * nod, st, mid, poz, val);
        } else {
            update(2 * nod + 1, mid + 1, dr, poz, val);
        }
        v[nod] = join(v[2 * nod], v[2 * nod + 1]);
    }
}
segTree query(int nod, int st, int dr, int x, int y) {
    int mid, nr1, nr2;
    segTree rez1, rez2;
    if (x <= st && y >= dr) {
        return v[nod];
    } else {
        mid = (st + dr) / 2;
        nr1 = nr2 = 0;
        if (x <= mid) {
            rez1 = query(2 * nod, st, mid, x, y);
            nr1 = 1;
        }
        if (y > mid) {
            rez2 = query(2 * nod + 1, mid + 1, dr, x, y);
            nr2 = 1;
        }
        if (nr1 + nr2 == 2) {
            return join(rez1, rez2);
        } else if (nr1 == 1) {
            return rez1;
        } else {
            return rez2;
        }
    }
}
int calcRez(segTree rez) {
    int nr, a, d;
    nr = 0;
    for (a = 0; a < 2; a++) {
        for (d = 0; d < 2; d++) {
            nr = (nr + rez.countLess[a][d] + rez.countEq[a][d]) % MOD;//nu pun long long ca countEq este 0 sau 1
        }
    }
    return nr;
}
int main()
{
    //aint in O(n + q * log(n)) cu constanta aproape 16 = 2^4 cred
    int n, q, i, cer, x, y;
    segTree rez;
    scanf("%d%d ", &n, &q);
    build(1, 1, n);
    printf("%d\n", calcRez(query(1, 1, n, 1, n)));
    for (i = 0; i < q; i++) {
        scanf("%d%d%d", &cer, &x, &y);
        if (cer == 1) {
            rez = query(1, 1, n, x, y);
            printf("%d\n", calcRez(rez));
        } else {
            update(1, 1, n, x, y);
        }
    }
    return 0;
}

Compilation message (stderr)

lucky.cpp: In function 'int main()':
lucky.cpp:122:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  122 |     scanf("%d%d ", &n, &q);
      |     ~~~~~^~~~~~~~~~~~~~~~~
lucky.cpp:126:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  126 |         scanf("%d%d%d", &cer, &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...