day-15

带修莫队

  • 修改记录时间,修改值,修改后值 同时读入修改时进行修改,修改结束后还原

const int maxn = 2e6 + 7;

int n, t, qn, m, k, a[maxn], ans[maxn], num[maxn], sum;
char op;

struct query {
    int l, r, t, id;
} q[maxn];

struct change {
    int pl, val, oval;
} chg[maxn];

bool cmp(query a, query b) {
    if (a.l / k != b.l / k) return a.l / k < b.l / k;
    if (a.r / k != b.r / k) return a.r / k < b.r / k;
    return a.t < b.t;
}

void add(int x) {
    if (x == 0)
        return;
    num[x]++;
    sum += (num[x] == 1);
}


void del(int x) {
    if (x == 0)
        return;
    num[x]--;
    sum -= (num[x] == 0);
}

int l = 1, r = 0, tn = 0;

void addchange(int t) {
    int pl = chg[t].pl, val = chg[t].val;
    if (pl >= l && pl <= r)
        add(val), del(a[pl]);
    a[pl] = val;
}

void delchange(int t) {
    int pl = chg[t].pl, val = chg[t].oval;
    if (pl >= l && pl <= r)
        add(val), del(a[pl]);
    a[pl] = val;
}

void solve() {
    cin >> n >> m;
    k = pow(n, 2.0 / 3);
    for (int i = 1; i <= n; i++) cin >> a[i];

    for (int i = 1, l, r; i <= m; i++) {
        cin >> op >> l >> r;
        if (op == 'R') chg[++t].pl = l, chg[t].val = r, chg[t].oval = a[l], a[l] = r;
        else q[++qn].l = l, q[qn].r = r, q[qn].t = t, q[qn].id = qn;
    }

    for (int i = t; i >= 1; i--) a[chg[i].pl] = chg[i].oval;

    sort(q + 1, q + 1 + qn, cmp);

    for (int i = 1; i <= qn; i++) {
        int L = q[i].l, R = q[i].r, T = q[i].t;

        while (tn < T) addchange(++tn);
        while (tn > T) delchange(tn--);
        while (l > L) add(a[--l]);
        while (r < R) add(a[++r]);
        while (l < L) del(a[l++]);
        while (r > R) del(a[r--]);

        ans[q[i].id] = sum;
    }
    for (int i = 1; i <= qn; i++)
        cout << ans[i] << "\n";
}
上一篇:PL lua源码剖析-云风.pdf


下一篇:工作笔记02——int切片转换为string类型/GO实现MAP的排序