zoukankan      html  css  js  c++  java
  • [模板]分块/可修改莫队 (数颜色种类)

    模板题地址

    题目描述

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

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

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

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

    范围N,M <=10000   每个数都<=10^6

    刚学会莫队就说说莫队:一种离线处理询问区间的好办法,虽然看上去超级暴力,但是很快。

    把询问按左右端点排序,每次移动两个端点在O(1)的时间内更新答案即可。

    while(L<q[i].l){/*O(1)更新答案*/L++;}
    while(L>q[i].l){L--;/*O(1)更新答案*/}
    while(R<q[i].r){R++;/*O(1)更新答案*/}
    while(R>q[i].r){/*O(1)更新答案*/R--;}

    当然还要用到分块的优化。

    P.S.排序以左端点所在的块为第一关键字,右端点为第二关键字

    struct Node{
        int l,r,id;
        bool operator <(const Node a){
            if(belong[l]==belong[a.l])return r<a.r;
            else return belong[l]<belong[a.l];
        }
    }q[MAXN];

    感觉是不是暴力得让人难以接受=、=  , 就是好用!

    然而话说回来这个题带上了修改。

    之前没有修改我们排序的是一个(l,r)

    带了修改就不妨加上一维时间轴,排序这个(l,r,t)

    再按照朴素的方法做,问题就迎刃而解了。

    代码

    #include<bits/stdc++.h>
    #define MAXN 10010
    using namespace std;
    int N,M,Q,siz,tim,a[MAXN],belong[MAXN],ans[MAXN],color[100010],tmp;
    struct Node{
        int l,r,id,t;
        bool operator <(const Node a){
            if(belong[l]==belong[a.l]){
                if(r==a.r)return t<a.t;
                else return r<a.r;
            }
            else return belong[l]<belong[a.l];
        }
    }q[MAXN];
    struct change{
        int x,y;
    }c[MAXN];
    void Change(int now,int i){
        if(c[now].x>=q[i].l&&c[now].x<=q[i].r){
            color[a[c[now].x]]--;
            if(color[a[c[now].x]]==0)tmp--;
            if(color[c[now].y]==0)tmp++;
            color[c[now].y]++;
        }
        swap(a[c[now].x],c[now].y);
    }
    int main()
    {
        scanf("%d%d",&N,&M);
        siz=sqrt(N);
        for(int i=1;i<=N;i++)scanf("%d",&a[i]),belong[i]=(i-1)/siz+1;
        for(int i=1;i<=M;i++){
            int a,b;char s[5];
            scanf("%s%d%d",s,&a,&b);
            if(s[0]=='Q')
                    q[++Q]=(Node){a,b,Q,tim};
            else     c[++tim]=(change){a,b}; 
        }
        sort(q+1,q+Q+1);
        int L=0,R=0,now=0;
        for(int i=1;i<=Q;i++){
            while(L<q[i].l){color[a[L]]--;if(color[a[L]]==0)tmp--;L++;}
            while(L>q[i].l){L--;color[a[L]]++;if(color[a[L]]==1)tmp++;}
            while(R<q[i].r){R++;color[a[R]]++;if(color[a[R]]==1)tmp++;}
            while(R>q[i].r){color[a[R]]--;if(color[a[R]]==0)tmp--;R--;}
            while(now<q[i].t){now++;Change(now,i);}
            while(now>q[i].t){Change(now,i);now--;}
            ans[q[i].id]=tmp;
        }
        for(int i=1;i<=Q;i++)
            printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    js正则匹配
    包含HTML的字符串去掉HTML标签
    smart-table 服务端请求真分
    禁用H5 表单验证novalidate
    webpack
    linux 进程查看及杀死进程
    配置ca服务器和http,mail加密
    mysql权限
    mysql查询
    mysql储存引擎
  • 原文地址:https://www.cnblogs.com/Elfish/p/7697851.html
Copyright © 2011-2022 走看看