• 【洛谷】1903:[国家集训队]数颜色 / 维护队列【带修莫队】


    P1903 [国家集训队]数颜色 / 维护队列

    题目描述

    墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问。墨墨会向你发布如下指令:

    1、 Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔。

    2、 R P Col 把第P支画笔替换为颜色Col。

    为了满足墨墨的要求,你知道你需要干什么了吗?

    输入输出格式

    输入格式:

     

    第1行两个整数N,M,分别代表初始画笔的数量以及墨墨会做的事情的个数。

    第2行N个整数,分别代表初始画笔排中第i支画笔的颜色。

    第3行到第2+M行,每行分别代表墨墨会做的一件事情,格式见题干部分。

    输出格式:

     

    对于每一个Query的询问,你需要在对应的行中给出一个数字,代表第L支画笔到第R支画笔中共有几种不同颜色的画笔。

    输入输出样例

    输入样例#1: 复制
    6 5
    1 2 3 4 5 5
    Q 1 4
    Q 2 6
    R 1 2
    Q 1 4
    Q 2 6
    输出样例#1: 复制
    4
    4
    3
    4
    

    说明

    对于100%的数据,N≤50000,M≤50000,所有的输入数据中出现的所有整数均大于等于1且不超过10^6。

    本题可能轻微卡常数

    来源:bzoj2120

    本题数据为洛谷自造数据,使用CYaRon耗时5分钟完成数据制作。


    Solution

    带修莫队模板题。

    如何完成有时间线的修改操作??在询问中加一个到它时修改操作到了哪一步的时间线,再像以前一样分块排序。

    计算答案时唯一不同的就是当把区间调成当前区间后,要看当前修改到哪一步,如果在它之前,那么就进行修改操作,更新答案。如果在它之后,那么进行撤销修改操作,更新答案。

    修改操作中有一步很巧妙,这次修改相当于是把$a[pos]$和当前修改的$col$交换,下次如果有撤销操作,那么就是从$col$修改到$a[pos]$了。

    洛谷数据加强后块要弄成$n^{frac{2}{3}}$才能过叻QAQ太玄学叻....

    Code

    #include<bits/stdc++.h>
    using namespace std;
    
    int n, a[500005], m;
    int blo[500005]; 
    
    void read(int &x) {
        x = 0; char ch = getchar();
        while(ch < '0' || ch > '9') ch = getchar();
        while(ch >= '0' && ch <= '9')
          x = x * 10 + ch - '0', ch = getchar();
    }
    
    struct Node {
        int l, r, id, ans, pos;
    } Q[500005];
    bool cmp(Node a, Node b) { 
        if(blo[a.l] != blo[b.l])    return a.l < b.l;
        if(blo[a.r] != blo[b.r])    return a.r < b.r;
        return a.id < b.id;
    }
    bool cmp2(Node a, Node b) { return a.pos < b.pos; }
    
    struct Edge {
        int pos, to;
    } C[500005];
    
    int L, R, cnttot, cnt[1000005];
    
    inline void update(int x) {
        if(C[x].pos >= L && C[x].pos <= R) {
            if(!--cnt[a[C[x].pos]])    -- cnttot;
            if(!cnt[C[x].to] ++) ++ cnttot;
        }
        swap(a[C[x].pos], C[x].to);
    }
    
    int main() {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i ++)    read(a[i]);
        int bl = pow(n, 0.666666666);
        for(int i = 1; i <= n; i ++)    blo[i] = i / bl + 1;
        int tot = 0, totc = 0;
        scanf("
    ");
        for(int i = 1; i <= m; i ++) {
            char opt;
            while(scanf("%c", &opt) == 1) if(opt == 'Q' || opt == 'R')    break;
            if(opt == 'Q') {
                int l, r;
                read(l); read(r);
                Q[++tot].l = l, Q[tot].r = r;
                Q[tot].id = totc, Q[tot].pos = i;
            } else {
                int x, col;
                read(x); read(col);
                ++ totc;
                C[totc].to = col, C[totc].pos = x;
            }
        }
        sort(Q + 1, Q + 1 + tot, cmp);
        int now = 0;
        for(int i = 1; i <= tot; i ++) {
            while(Q[i].l < L) {
                L --;
                if(!cnt[a[L]]++)    cnttot ++;
            }
            while(Q[i].l > L) {
                if(!--cnt[a[L]])    cnttot --;
                L ++;
            }
            while(Q[i].r < R) {
                if(!--cnt[a[R]])    cnttot --;
                R --;
            }
            while(Q[i].r > R) {
                R ++;
                if(!cnt[a[R]]++)    cnttot ++;
            }
            while(now < Q[i].id) update(++now);
            while(now > Q[i].id) update(now--);
            Q[i].ans = cnttot;
        }
        sort(Q + 1, Q + 1 + tot, cmp2);
        for(int i = 1; i <= tot; i ++)
            printf("%d
    ", Q[i].ans);
        return 0;
    }
  • 相关阅读:
    setAnimationTransition:forView:cache: 运行动画时背景色问题
    架构师速成4.6-软技能和硬技能
    Java获取某年某周的第一天
    openssl之BIO系列之12---文件描写叙述符(fd)类型BIO
    centos 使用 CP 命令 不提示 覆盖
    [3 Jun 2015 ~ 9 Jun 2015] Deep Learning in arxiv
    P1314 聪明的质监员
    P2858 [USACO06FEB]奶牛零食Treats for the Cows
    1163 访问艺术馆
    P1352 没有上司的舞会
  • 原文地址:https://www.cnblogs.com/wans-caesar-02111007/p/9776111.html
Copyright © 2020-2023  润新知