• Bzoj2120/洛谷P1903 数颜色(莫队)


    题面

    Bzoj

    洛谷

    题解

    考虑对操作离线后分块处理询问操作(莫队算法),将询问操作按照编号分块后左端点第一关键字,右端点第二关键字排序(分块大小为$n^{frac 23}$),对于每一个询问操作,记下当前最后一个修改操作。

    之后就是莫队的板子了。

    #include <set>
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using std::min; using std::max;
    using std::swap; using std::sort;
    typedef long long ll;
    using std::set;
    
    template<typename T>
    void read(T &x) {
        int flag = 1; x = 0; char ch = getchar();
        while(ch < '0' || ch > '9') { if(ch == '-') flag = -flag; ch = getchar(); }
        while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); x *= flag;
    }
    
    const int N = 2e6 + 10, M = 5e4 + 10;
    int n, m, siz, col[M], l, r, tot[N], ans[M], ret, now, bel[M];
    struct Ques { int x, y, z, pre; } q[M]; int cntqu;
    struct Modi { int pos, val; } o[M]; int cntmo;
    inline bool cmp (const Ques &a, const Ques &b) {
        if(bel[a.z] != bel[b.z]) return bel[a.z] < bel[b.z];
        if(a.x != b.x) return a.x < b.x;
        if(a.y != b.y) return a.y < b.y;
        return a.pre < b.pre;
    }
    
    inline void del (int c) { if(--tot[c] == 0) --ret; }
    inline void add (int c) { if(++tot[c] == 1) ++ret; }
    inline void doit (int now, int k) {
        if(o[now].pos >= q[k].x && o[now].pos <= q[k].y)
            del(col[o[now].pos]), add(o[now].val);
        swap(col[o[now].pos], o[now].val);
        //将操作记忆化,当处理替换时,相当于换过去,撤销时,相当于换回来。
    }
    
    int main () {
        read(n), read(m), siz = pow(n, 0.66666666);
        for(int i = 1; i <= n; ++i)
            read(col[i]), bel[i] = (i - 1) / siz + 1;
        char opt;
        while(m--) {
            scanf("
    %c", &opt);
            if(opt == 'Q') {
                read(q[++cntqu].x), read(q[cntqu].y);
                q[cntqu].z = cntqu, q[cntqu].pre = cntmo;
            } else read(o[++cntmo].pos), read(o[cntmo].val); 
        }
        sort(&q[1], &q[cntqu + 1], cmp), l = 1;
        for(int i = 1; i <= cntqu; ++i) {
            while(l < q[i].x) del(col[l++]);
            while(l > q[i].x) add(col[--l]);
            while(r < q[i].y) add(col[++r]);
            while(r > q[i].y) del(col[r--]);
            while(now < q[i].pre) doit(++now, i);
            while(now > q[i].pre) doit(now--, i);
            ans[q[i].z] = ret;
        }
        for(int i = 1; i <= cntqu; ++i)
            printf("%d
    ", ans[i]);
        return 0;
    } 
    
  • 相关阅读:
    Java实现约瑟夫环问题
    Java实现约瑟夫环问题
    mysql远程表链接
    linux下mysql定时备份
    深入浅出RPC——浅出篇(转载)
    深入浅出RPC——深入篇(转载)
    Qt在Windows上的调试器安装与配置
    VS2015 ASP.NET5 Web项目
    jquery validate remote验证唯一性
    jQuery UI框架
  • 原文地址:https://www.cnblogs.com/water-mi/p/10303807.html
Copyright © 2020-2023  润新知