2021CCPC桂林 B. A Plus B Problem

裸线段树板题,非常恶心

#include<bits/stdc++.h>

using namespace std;
const int N = 1e6 + 10;
struct {
    int l, r, len;
    int val, suf0, suf9;
    bool tag0, tag9;
} t[N << 2];
int a[2][N], b[N];

inline void update(int p) {
    if (t[p << 1 | 1].suf0 == t[p << 1 | 1].len)
        t[p].suf0 = t[p << 1 | 1].len + t[p << 1].suf0;
    else t[p].suf0 = t[p << 1 | 1].suf0;
    if (t[p << 1 | 1].suf9 == t[p << 1 | 1].len)
        t[p].suf9 = t[p << 1 | 1].len + t[p << 1].suf9;
    else t[p].suf9 = t[p << 1 | 1].suf9;
}

inline void spread(int p) {
    if (t[p].tag0) {
        t[p << 1].val = 0;
        t[p << 1].suf0 = t[p << 1].len;
        t[p << 1].suf9 = 0;
        t[p << 1].tag0 = true;
        t[p << 1].tag9 = false;
        t[p << 1 | 1].val = 0;
        t[p << 1 | 1].suf0 = t[p << 1 | 1].len;
        t[p << 1 | 1].suf9 = 0;
        t[p << 1 | 1].tag0 = true;
        t[p << 1 | 1].tag9 = false;
        t[p].tag0 = false;
    }
    if (t[p].tag9) {
        t[p << 1].val = 9;
        t[p << 1].suf9 = t[p << 1].len;
        t[p << 1].suf0 = 0;
        t[p << 1].tag9 = true;
        t[p << 1].tag0 = false;
        t[p << 1 | 1].val = 9;
        t[p << 1 | 1].suf9 = t[p << 1 | 1].len;
        t[p << 1 | 1].suf0 = 0;
        t[p << 1 | 1].tag9 = true;
        t[p << 1 | 1].tag0 = false;
        t[p].tag9 = false;
    }
}

void build(int p, int l, int r) {
    t[p].l = l, t[p].r = r, t[p].len = r - l + 1;
    if (l == r) {
        t[p].suf0 = (b[l] == 0);
        t[p].suf9 = (b[l] == 9);
        t[p].val = b[l];
        return;
    }
    int mid = (l + r) >> 1;
    build(p << 1, l, mid);
    build(p << 1 | 1, mid + 1, r);
    update(p);
}

int ask0(int p, int x) {
    if (t[p].suf0 == t[p].len)return min(x, t[p].r) - t[p].l + 1;
    if (t[p].l == t[p].r) return t[p].val == 0;
    spread(p);
    int mid = (t[p].l + t[p].r) >> 1;
    if (x > mid) {
        int len = ask0(p << 1 | 1, x);
        if (len == min(x, t[p << 1 | 1].r) - t[p << 1 | 1].l + 1)
            len += ask0(p << 1, x);
        return len;
    }
    return ask0(p << 1, x);
}

int ask9(int p, int x) {
    if (t[p].suf9 == t[p].len)return min(x, t[p].r) - t[p].l + 1;
    if (t[p].l == t[p].r) return t[p].val == 9;
    spread(p);
    int mid = (t[p].l + t[p].r) >> 1;
    if (x > mid) {
        int len = ask9(p << 1 | 1, x);
        if (len == min(x, t[p << 1 | 1].r) - t[p << 1 | 1].l + 1)
            len += ask9(p << 1, x);
        return len;
    }
    return ask9(p << 1, x);
}

int ask(int p, int x) {
    if (t[p].l == t[p].r)return t[p].val;
    spread(p);
    int mid = (t[p].l + t[p].r) >> 1;
    if (x <= mid)return ask(p << 1, x);
    return ask(p << 1 | 1, x);
}

void change0(int p, int l, int r) {
    if (l <= t[p].l && t[p].r <= r) {
        t[p].val = 0;
        t[p].suf0 = t[p].len;
        t[p].suf9 = 0;
        t[p].tag0 = true;
        t[p].tag9 = false;
        return;
    }
    spread(p);
    int mid = (t[p].l + t[p].r) >> 1;
    if (l <= mid)change0(p << 1, l, r);
    if (r > mid)change0(p << 1 | 1, l, r);
    update(p);
}

void change9(int p, int l, int r) {
    if (l <= t[p].l && t[p].r <= r) {
        t[p].val = 9;
        t[p].suf0 = 0;
        t[p].suf9 = t[p].len;
        t[p].tag0 = false;
        t[p].tag9 = true;
        return;
    }
    spread(p);
    int mid = (t[p].l + t[p].r) >> 1;
    if (l <= mid)change9(p << 1, l, r);
    if (r > mid)change9(p << 1 | 1, l, r);
    update(p);
}

void change(int p, int x, int v) {
    if (t[p].l == t[p].r) {
        t[p].val = v;
        t[p].suf0 = (v == 0);
        t[p].suf9 = (v == 9);
        return;
    }
    spread(p);
    int mid = (t[p].l + t[p].r) >> 1;
    if (x <= mid)change(p << 1, x, v);
    else change(p << 1 | 1, x, v);
    update(p);
}


int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++)scanf("%1d", &a[0][i]);
    for (int i = 1; i <= n; i++)scanf("%1d", &a[1][i]);
    for (int i = n, u = 0; i >= 1; i--) {
        b[i] = a[0][i] + a[1][i] + u;
        u = b[i] / 10, b[i] %= 10;
    }
    build(1, 1, n);
    while (m--) {
        int r, c, d;
        scanf("%d%d%d", &r, &c, &d), --r;
        d = d - a[r][c], a[r][c] += d;
        int val = ask(1, c) + d;

        if (d == 0) {
            printf("%d 0\n", val);
            continue;
        }
        if (val <= 9 && val >= 0 || c == 1) {
            val = (val + 10) % 10;
            change(1, c, val);
            printf("%d 2\n", val);
            continue;
        }
        if (val > 9) {
            int len = ask9(1, c - 1);
            change(1, c, val - 10);
            if (len)change0(1, c - len, c - 1);
            if (c - len - 1 >= 1) {
                change(1, c - len - 1, ask(1, c - len - 1) + 1);
                printf("%d %d\n", val - 10, len + 3);
            } else printf("%d %d\n", val - 10, len + 2);
            continue;
        }
        int len = ask0(1, c - 1);
        change(1, c, val + 10);
        if (len)change9(1, c - len, c - 1);
        if (c - len - 1 >= 1) {
            change(1, c - len - 1, ask(1, c - len - 1) - 1);
            printf("%d %d\n", val + 10, len + 3);
        } else printf("%d %d\n", val + 10, len + 2);
    }
    return 0;
}
上一篇:TRMF 辅助论文:最小二乘法复现TRMF


下一篇:AD域用户密码策略_AD域用户如何自助管理密码?