BZOJ 2120 带修改莫队

来源:互联网 发布:python常用包 编辑:程序博客网 时间:2024/06/05 03:30

简略题意:单点修改,区间查询不同颜色个数。

带修改莫队的板题,学习了一个。
和普通莫队的区别在于块的大小需要设定为n2/3,这样可以确保复杂度为O(n3/5)
每次询问之前需要把在当前时间点之前的所有修改用上,这之后的所有修改删掉。

#define others#ifdef poj#include <iostream>#include <cstring>#include <cmath>#include <cstdio>#include <algorithm>#include <vector>#endif // poj#ifdef others#include <bits/stdc++.h>#endif // others//#define file#define all(x) x.begin(), x.end()using namespace std;const double eps = 1e-8;int dcmp(double x) { if(fabs(x)<=eps) return 0; return (x>0)?1:-1;};typedef long long LL;typedef unsigned long long ULL;void file() {    freopen("out.txt", "r", stdin);    freopen("out1.txt", "w", stdout);}namespace Solver {    const int maxn = 11000;    int val[maxn], ans[maxn];    int col[1100000];    int res;    int n, m, q;    int sz;    int L = 1, R = 0, T = 0;    struct Mo {        int l, r, t, id;        bool operator < (const Mo & b) const {            if(l/sz != b.l/sz) return l/sz < b.l/sz;            if(r/sz != b.r/sz) return r/sz < b.r/sz;            return t < b.t;        }    } ask[maxn];    bool cmp(Mo a, Mo b) {        return a.id < b.id;    }    struct Mo_sub {        int x, y, z;    } upd[maxn];    void del(int x) {        col[val[x]]--;        if(col[val[x]] == 0) res--;    }    void ins(int x) {        if(col[val[x]] == 0) res++;        col[val[x]] ++;    }    void time_ins(int t) {        int x = upd[t].x, y = upd[t].y, &pre = upd[t].z;        if(x >= L && x <= R) del(x);        pre = val[x];        val[x] = y;        if(x >= L && x <= R) ins(x);    }    void time_del(int t) {        int x = upd[t].x, y = upd[t].y, pre = upd[t].z;        if(x >= L && x <= R) del(x);        val[x] = pre;        if(x >= L && x <= R) ins(x);    }    void solve() {        scanf("%d%d", &n, &m);        sz = powf(n, 2.0/3);        for(int i = 1; i <= n; i++) scanf("%d", &val[i]);        int cnt1, cnt2; cnt1 = cnt2 = 0;        for(int i = 1; i <= m; i++) {            char ch; int x, y;            scanf(" %c%d%d", &ch, &x, &y);            if(ch == 'Q')                cnt1++, ask[cnt1] = {x, y, cnt2, i};            else                cnt2++, upd[cnt2] = {x, y, 0};        }        sort(ask+1, ask+1+cnt1);        for(int i = 1; i <= cnt1; i++) {            while(L < ask[i].l) del(L), L++;            while(R < ask[i].r) R++, ins(R);            while(L > ask[i].l) L--, ins(L);            while(R > ask[i].r) del(R), R--;            while(T > ask[i].t) time_del(T), T--;            while(T < ask[i].t) T++, time_ins(T);            ans[ask[i].id] = res;        }        sort(ask+1, ask+1+cnt1, cmp);        for(int i = 1; i <= cnt1; i++) printf("%d\n", ans[ask[i].id]);    }}int main() {    Solver::solve();    return 0;}
原创粉丝点击