? Sum Queries CodeForces - 1217E (segment tree)

? Sum Queries CodeForces - 1217E (segment tree)

Meaning of the questions:

It is defined as a set of \ (Balanced \) , and if and only if the sum of the numbers of each set of decimal digits, the bits are set to a same number. Otherwise, the collection is called \ (unbalanced \) it is.

Given a length \ (n-\) sequence, \ (Q \) time interval within a number of interrogation and minimal \ (unbalanced \) set output digital sum. If there is no output \ (--1 \) .

\(n,q<=200000\)

answer:

Can be found, if there \ (unbalanced \) collection, the minimum must be composed of a collection of just two numbers. The presence of these two numbers are not a decimal digit \ (0 \) .

The establishment of ten tree line, this bit of non-maintenance each position (0 \) \ interval minimum, update the answer when updating minimum. If the query, if the query interval required separately, do not forget to number between a plurality of sections after separation also affect each other, you should enumerate each decimal digits, the minimum merge multiple intervals to update the answer.

Time complexity \ (O (10 × (n-m +) log (n-)) \) .

Code:

#include <bits/stdc++.h>
#define fopi freopen("in.txt", "r", stdin)
#define fopo freopen("out.txt", "w", stdout)
using namespace std;
const int inf = 2e9 + 10;
const int maxn = 2e5 + 10;

struct Node {
    int l, r, Min[12];
}t[maxn*4];
int Ans[maxn*4], a[maxn], tmp[maxn];
int ans;

void push_up(int id) {
    Ans[id] = inf;
    for (int i = 1; i <= 10; i++) {
        if (t[id*2].Min[i] < inf && t[id*2+1].Min[i] < inf)
            Ans[id] = min(Ans[id], t[id*2].Min[i] + t[id*2+1].Min[i]);
        t[id].Min[i] = min(t[id*2].Min[i], t[id*2+1].Min[i]);
    }
    Ans[id] = min(Ans[id], min(Ans[id*2], Ans[id*2+1]));
}

void build(int id, int l, int r) {
    Ans[id] = inf;
    t[id].l = l, t[id].r = r;
    if (l == r) {
        int res = a[l];
        for (int i = 1; i <= 10; i++) {
            if (res % 10 == 0) t[id].Min[i] = inf;
            else t[id].Min[i] = a[l];
            res /= 10;
        }
        return;
    }
    int mid = (l+r) / 2;
    build(id*2, l, mid), build(id*2+1, mid+1, r);
    push_up(id);
}

void update(int id, int l, int x) {
    if (t[id].l == l && t[id].r == l) {
        int res = x;
        for (int i = 1; i <= 10; i++) {
            if (res % 10 == 0) t[id].Min[i] = inf;
            else t[id].Min[i] = x;
            res /= 10;
        }
        return;
    }
    int mid = (t[id].l + t[id].r) / 2;
    if (l <= mid) update(id*2, l, x);
    else update(id*2+1, l, x);
    push_up(id);
}

void query(int id, int l, int r) {
    if (l <= t[id].l && r >= t[id].r) {
        for (int i = 1; i <= 10; i++) {
            if (tmp[i] < inf && t[id].Min[i] < inf) {
                ans = min(ans, tmp[i] + t[id].Min[i]);
            }
            tmp[i] = min(tmp[i], t[id].Min[i]);
        }
        ans = min(ans, Ans[id]);
        return;
    }
    int mid = (t[id].l + t[id].r) / 2;
    if (r <= mid) query(id*2, l, r);
    else if (l > mid) query(id*2+1, l, r);
    else query(id*2, l, mid), query(id*2+1, mid+1, r);
}

int n, m, res;
int main() {
    //fopi;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    build(1, 1, n);
    for (int i = 1; i <= m; i++) {
        int op, x, y;
        scanf("%d%d%d", &op, &x, &y);
        if (op == 1) update(1, x, y);
        else {
            for (int i = 1; i <= 10; i++) tmp[i] = inf;
            ans = inf;
            query(1, x, y);
            printf("%d\n", ans >= inf ? -1 : ans);
        }
    }
}

Guess you like

Origin www.cnblogs.com/ruthank/p/11514797.html