1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
| #include <bits/stdc++.h> using namespace std; typedef long long LL; const int MAX_N = 200000 + 5; const int MAX_S = 10; const int INF = INT_MAX; int tree[MAX_N * 4][MAX_S], opt[MAX_N * 4]; inline int ls(int o) { return o << 1; } inline int rs(int o) { return o << 1 | 1; } inline void pushUp(int o) { opt[o] = min(opt[ls(o)], opt[rs(o)]); for (int i = 0; i < 10; ++i) { tree[o][i] = min(tree[ls(o)][i], tree[rs(o)][i]); if (tree[ls(o)][i] != INF && tree[rs(o)][i] != INF) { opt[o] = min(opt[o], tree[ls(o)][i] + tree[rs(o)][i]); } } } void build(int o, int l, int r) { if (l == r) { opt[o] = INF; for (int i = 0; i < 10; ++i) { tree[o][i] = INF; } return; } int mid = (l + r) >> 1; build(ls(o), l, mid); build(rs(o), mid + 1, r); pushUp(o); } void update(int o, int l, int r, int pos, int val) { if (l == r) { int v = val; for (int i = 0; i < 10; ++i) { int u = v % 10; if (!u) tree[o][i] = INF; else tree[o][i] = val; v /= 10; } return; } int mid = (l + r) >> 1; if (pos <= mid) update(ls(o), l, mid, pos, val); else update(rs(o), mid + 1, r, pos, val); pushUp(o); } struct Node { int uOpt, uT[MAX_S]; Node() { for (int i = 0; i < 10; ++i) uT[i] = INF; uOpt = INF; } }; Node query(int o, int l, int r, int L, int R) { if (L <= l && r <= R) { Node u; for (int i = 0; i < 10; ++i) { u.uT[i] = tree[o][i]; } u.uOpt = opt[o]; return u; } int mid = (l + r) >> 1; if (R <= mid) return query(ls(o), l, mid, L, R); if (L > mid) return query(rs(o), mid + 1, r, L, R); Node uL = query(ls(o), l, mid, L, R), uR = query(rs(o), mid + 1, r, L, R); Node u; u.uOpt = min(uL.uOpt, uR.uOpt); for (int i = 0; i < 10; ++i) { u.uT[i] = min(uL.uT[i], uR.uT[i]); if (uL.uT[i] != INF && uR.uT[i] != INF) u.uOpt = min(u.uOpt, uL.uT[i] + uR.uT[i]); } return u; } int n, m; int a[MAX_N]; int main() { scanf("%d%d", &n, &m); build(1, 1, n); for (int i = 1; i <= n; ++i) scanf("%d", a + i), update(1, 1, n, i, a[i]); for (int i = 1; i <= m; ++i) { int op, u, v; scanf("%d%d%d", &op, &u, &v); if (op == 1) update(1, 1, n, u, v); else { Node ans = query(1, 1, n, u, v); if (ans.uOpt == INF) puts("-1"); else printf("%d\n", ans.uOpt); } } return 0; }
|